leetcode 672之Bulb Switcher II
原題:
我用中文簡述一下題幹:
上面的四個方塊是四個燈泡按鈕,
下面的一系列橢圓是一組燈泡,初始狀態全亮。
上面四個按鈕的作用分別是:
全:按一下則所有燈泡切換狀態(從亮到黑, 或從黑到亮)
偶:所有偶數位燈泡切換狀態
奇:所有奇數位燈泡切換狀態
隔三: 所有1+3k(k=0,1,2...)燈泡切換狀態(也就是圖中黃色標註的這些位置)
現在給定燈泡個數n,以及確定的按燈泡的次數m(每次只能按一個按鈕),求最終燈泡序列的狀態組合有可能有多少種。
例如n=1,m=1,則最終燈泡序列的狀態可能為[on], [off],即2種,返回2
再如n=2,m=1, 則最終燈泡序列的狀態可能為 [on, off], [off, on], [off, off],即3種,返回2.
====以上是我對題乾的解讀,總感覺有時候Leetcode題乾的表述不是那麼清晰。不過我這裡翻譯如此。
解題思路:
關於最終狀態的求解,本質上是從初始狀態經過一些列操作演化而來,那麼如果可以先求出這一系列按燈泡操作本身的組合數x,就相當於確定了最終燈泡狀態的上限,再排除這x個組合中可能導致燈泡狀態結果重合的情況(即兩種不同的操作序列導致同一個燈泡狀態的情況),就可以求出最終結果。
求這個操作組合數x,即四個按鈕按m次,換一種思路就是:有四個槽,往裡投幣m次,可重複投同一個槽,最終槽位狀態會是裡面分別有多少個幣。然而再細想一下,這個問題還可以做一個等價的轉換,每個槽只要有2個硬幣,就可以像俄羅斯方塊一樣消去,因為同一個按鈕按任意偶數次都相當於沒按,那麼依照這種思路,最終每槽位中可能的狀態只能是0或者1,分別代表不按或者按,考慮到槽位總共只有4個,那麼槽位狀態的組合最多隻有2^4=16種,這就是我們要求的最終燈泡狀態的上限。這一點很重要,如果不做這樣的等價轉換,則組合數可能非常大,再從這些組合數中去推敲另一個組合數,計算量就會很大。
那麼如何求出具體有哪些按鈕操作組合情況呢?既然上面說了上限只有16種,所以是一個跟m規模無關的問題,與其根據m去求,不如拿16種狀態一個個去驗證, 驗證通過即為一種組合情況。為了方便,可以用4位二進位制數來代表(從0000到1111),例如1001表示按“全”和“隔三”兩個按鈕, 1100,代表按“全”和“偶”兩個按鈕,以此類推。。。有了這種代表方式後,如何驗證m次操作可以達到這種等價狀態呢?很簡單,考慮這個例子:1110這個狀態能否通過5次操作達到等價操作?可以,因為這個序列中有3個1,那麼我先把5次中的三次按照順序給按了,剩下兩次(偶數次)隨便挑一個按鈕給按了(上面說了,任意按偶數次按鈕等價於沒按),根據這個例子可以知道一個原則,我們先看最後這個狀態序列碼中有多少個1,再拿m去比對,如果m比1的個數還少,那麼顯然達不到,如果正好相等,那麼一定可以達到,如果m大於這個數,則看大出多少,如果大出的數是偶數,則可以達到。
通過以上方式,就可以求出所有m次操作可達的等價操作序列。下一步就是確定兩個操作序列應用於n個燈泡時,是否可能達到同一個燈泡序列狀態,這一步求解思路如下:假如我們要判斷1001和1110這兩個操作序列能否使燈泡達到同狀態,可以通過找這兩個序列碼的“編輯距離”來算,所謂“編輯距離”就是從狀態A變化到狀態B要經過哪些碼位變換(即同一位置的狀態翻轉),例如從1001到1110需要經過哪些變換呢?首先,第一位相同,不需要變換,變換操作記為0,第二位狀態不同,變換操作記為1,第三位第四位也不同,都記為1,那麼可以記為兩種狀態的“編輯距離為0111,也就是從1001這個狀態切換到1110這個狀態,只需要做0111對應的操作即可達到。
那麼再回過頭來看,我們的目的是求1001和1110這兩種操作序列能否達到相同同燈泡狀態,而我們又說了通過0111這個操作可以從1001達到1110,那麼可想而知,可達相同燈泡狀態的等價於說這個我們操作了這個0111這個操作等價於不改變任何燈泡狀態。或者換種說法,有三種操作序列A, B, C,分別對應一組按鈕操作,並且A+B=C, 如果我們知道A和C對應著同樣的燈泡序列,那麼B必然意味著等價於啥也沒做。而“啥也沒做”意味著對任意燈泡,都啥也沒做或者做了偶數次同按鈕操作。
以上就是全部的思路。程式碼實現如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
已通過leetcode online judge