前往
大廳
主題

LeetCode - 957. Prison Cells After N Days 解題心得

Not In My Back Yard | 2021-12-01 00:00:03 | 巴幣 100 | 人氣 168

題目連結:


題目意譯:
現在有 8 個監獄牢房排成一列,且每個牢房要嘛被佔用要嘛是空的。

每天,牢房會不會被佔用是根據以下規則而演變:
如果一個牢房有著兩個相鄰牢房皆被佔用或是皆空,則該牢房將會被佔用。
反之,其將變為空的。

注意因為監獄是一列的,因此列中第一個間與最後一間牢房沒有兩個相鄰牢房。

你被給定一個整數陣列 cells,其中 cells[i] == 1 如果第 i 間牢房有被佔用而 cells[i] == 0 如果第 i 間牢房是空的。且你被給定一個整數 n。

回傳 n 天後(即 n 次上述的變化)的監獄狀態。

限制:
cells.length == 8
cells[i] 只會是 0 或是 1。
1 ≦ n ≦ 10 ^ 9



範例測資:
範例 1:
輸入: cells = [0,1,0,1,1,0,0,1], n = 7
輸出: [0,0,1,1,0,0,0,0]
解釋: 如下列表總結了每天的監獄狀態:
第 0 天: [0, 1, 0, 1, 1, 0, 0, 1]
第 1 天: [0, 1, 1, 0, 0, 0, 0, 0]
第 2 天: [0, 0, 0, 0, 1, 1, 1, 0]
第 3 天: [0, 1, 1, 0, 0, 1, 0, 0]
第 4 天: [0, 0, 0, 0, 0, 1, 0, 0]
第 5 天: [0, 1, 1, 1, 0, 1, 0, 0]
第 6 天: [0, 0, 1, 0, 1, 1, 0, 0]
第 7 天: [0, 0, 1, 1, 0, 0, 0, 0]

範例 2:
輸入: cells = [1,0,0,1,0,0,1,0], n = 1000000000
輸出: [0,0,1,1,1,1,1,0]


解題思維:
因為牢房狀態只會是 0 或是 1,而我們只有八個房間。所以我們最多只會有 2 ^ 8 = 256 種狀態,因此我們最長每 256 天就會循環一次。

不過我們可以看到第 1 天(含)之後最左和最右側的牢房將永遠都是 0(因為那兩間沒有完整的「兩側」)。所以我們可以把循環長度降到 2 ^ 6 = 64 天。

因此我們可以直接迭代 64 天,直到我們碰到重複的狀態時,計算其距離第 1 天的天數即可得循環節長度 K。所以題目給的 n 值再怎麼大,我們都可以將其降到等價於 ≦ K 的情況。



但是如果我們多試幾個狀態,可以觀察到每過 7 天(第 1 天對第 8 天、第 8 天對第 15 天等等)就必定會出現一個現象:本天的狀態會是七天前的狀態,但是是左右鏡像的(即左右翻轉)。

因此每過 14 天,我們將會返回到第 1 天的狀態(因為我們左右翻轉了兩次)。而這可以利用程式窮舉每個狀態檢查,或是直接爆開出以下的狀態圖:
如上圖我們可以看到過 7 天後,整個狀態便左右翻轉了。

因此我們最終只需要按照原本的迭代方式,而這次連找循環節都不用(可以直接假設固定都是 14 天)便可以得到第 n 天的等價狀態。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作