復(fù)雜度分析之leetcode: Move Zeros

今天做了一道leetcode小題蕴侧,題目叫Move Zeros府蛇,地址在這里leetcode: Move Zeros腺怯。

題目很簡(jiǎn)單(我就是在挑簡(jiǎn)單的題找自信),感覺是一個(gè)使用復(fù)雜度分析的好例子诽俯,簡(jiǎn)單易懂妇菱。我們一步步來,先來看一下題目暴区。

Move Zeros

Given an arraynums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

For example, givennums = [0, 1, 0, 3, 12], after calling your function,nums should be[1, 3, 12, 0, 0].

Note:

  1. You must do this in-place without making a copy of the array.
  2. Minimize the total number of operations.

題目并不復(fù)雜闯团,就是把一個(gè)數(shù)組里邊兒的零都移到末尾。唯一需要注意的是颜启,它要求“in-place”--就地解決偷俭,不能使用額外的存儲(chǔ)空間,比如拷貝數(shù)組的操作是不允許的缰盏。

看完題目以后先思考幾分鐘吧涌萤。下面幾節(jié)淹遵,我會(huì)描述一下我的思考過程。

原子操作

題目要求“in-place”的解決负溪,那么我們這時(shí)候可以做哪些操作呢透揣?

  • 賦值
    修改列表(數(shù)組)元素的值是可以的,這是對(duì)現(xiàn)有內(nèi)存的操作川抡,不會(huì)使用額外的空間辐真。

  • 交換
    賦值可以,那么交換可以嗎崖堤?我們常用的交換是三次賦值侍咱,使用一塊臨時(shí)空間,像這樣:

     tmp = a[i]
     a[i] = a[j]
     a[j] = tmp
    

    還有不使用額外空間的技巧密幔,像這樣:

      a[i] = a[i] + a[j]
      a[j] = a[i] - a[j]
      a[i] = a[i] - a[j]
    

    所以楔脯,只要賦值操作可以做,交換就可以胯甩。

你還能想到其它的操作么昧廷?想到了一定告訴我,反正我沒想到偎箫。

題目的任務(wù)現(xiàn)在可以理解成這樣:通過賦值或者交換的手段木柬,在不破壞非零元素順序的情況下,把所有的零元素移到列表的末尾淹办。

O(n^2)

我首先想到的算法是基于交換的眉枕。以題目中給出的示例為例:

    [0, 1, 0, 3, 12] => [1, 3, 12, 0, 0]

觀察上面的例子,我們發(fā)現(xiàn)兩點(diǎn)事實(shí):

  1. 終結(jié)狀態(tài)是確定的娇唯,一個(gè)初始狀態(tài)必然對(duì)應(yīng)一個(gè)確定的終結(jié)狀態(tài)齐遵;
  2. 由于元素的值是不可變的,所以終結(jié)狀態(tài)和初始狀態(tài)的差別只是元素位置的差別塔插。

根據(jù)以上事實(shí),從終結(jié)狀態(tài)出發(fā)可以推理出拓哟,當(dāng)一個(gè)零元素的位置不正確的時(shí)候想许,必然占據(jù)了另一個(gè)非零元素的正確位置。

    [0, 1, 0, 3, 12] => [1, 3, 12, 0, 0] # 第一個(gè)元素“0”断序,占據(jù)了元素“1”的位置

如果我們能夠找到那個(gè)非零元素流纹,讓兩者交換位置,就可以讓非零元素進(jìn)入正確的位置违诗。

    [0, 1, 0, 3, 12] => [1, 0, 0, 3, 12] # 一次交換漱凝,元素“1”進(jìn)入正確的位置

由于零元素的位置不需要精確(零元素的排列順序無意義),所以只要保證所有的非零元素的位置正確诸迟,我們就得到正確的結(jié)果了茸炒,如下

    [0, 1, 0, 3, 12] => [1, 0, 0, 3, 12] # 一次交換愕乎,元素“1”進(jìn)入正確的位置
    [1, 0, 0, 3, 12] => [1, 3, 0, 0, 12] # 二次交換,元素“3”進(jìn)入正確的位置
    [1, 3, 0, 0, 12] => [1, 3, 12, 0, 0] # 三次交換壁公,元素“12”進(jìn)入正確的位置

最后回答一個(gè)問題感论,零元素占據(jù)了那個(gè)非零元素的位置?因?yàn)榉橇阍氐挠行蛐晕刹幔@然是從左往右最靠近它的非零元素比肄。

根據(jù)以上分析,我們構(gòu)建以下算法:

    def moveNums(nums):
        # 遍歷列表
        for i in range(len(nums)):
            # 如果發(fā)現(xiàn)零元素囊陡,就向右尋找最靠近它的非零元素芳绩,交換兩者位置
            if nums[i] == 0:
                for j in range(i+1, len(nums)):
                    if nums[j] != 0:
                        nums[i] = nums[j]
                        nums[j] = 0 
                        break

        return nums

這個(gè)算法的復(fù)雜度很好分析,兩個(gè)"for-loop"的結(jié)構(gòu)撞反,顯然是O(n^2)的示括。在leetcode上提交后的結(jié)果如下:

leetcode Submission Analysis

可以看到全部的“testcase”都通過了,但執(zhí)行效率只打敗了約3%的“Python Submission”痢畜。顯然垛膝,這個(gè)算法的復(fù)雜度偏高了,還有更好的方法丁稀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吼拥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子线衫,更是在濱河造成了極大的恐慌凿可,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件授账,死亡現(xiàn)場(chǎng)離奇詭異枯跑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)白热,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門敛助,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屋确,你說我怎么就攤上這事纳击。” “怎么了攻臀?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵焕数,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我刨啸,道長(zhǎng)堡赔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任设联,我火速辦了婚禮善已,結(jié)果婚禮上灼捂,老公的妹妹穿的比我還像新娘。我一直安慰自己雕拼,他們只是感情好纵东,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啥寇,像睡著了一般偎球。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辑甜,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天衰絮,我揣著相機(jī)與錄音,去河邊找鬼磷醋。 笑死猫牡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邓线。 我是一名探鬼主播淌友,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼骇陈!你這毒婦竟也來了震庭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤你雌,失蹤者是張志新(化名)和其女友劉穎器联,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婿崭,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拨拓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氓栈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渣磷。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖颤绕,靈堂內(nèi)的尸體忽然破棺而出幸海,到底是詐尸還是另有隱情,我是刑警寧澤奥务,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站袜硫,受9級(jí)特大地震影響氯葬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜婉陷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一帚称、第九天 我趴在偏房一處隱蔽的房頂上張望官研。 院中可真熱鬧,春花似錦闯睹、人聲如沸戏羽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽始花。三九已至,卻和暖如春孩锡,著一層夾襖步出監(jiān)牢的瞬間酷宵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工躬窜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浇垦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓荣挨,卻偏偏與公主長(zhǎng)得像男韧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子默垄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容