每日演算法系列 LeetCode 289 生命遊戲

2021-10-02 15:42:20 字數 2151 閱讀 9356

給定乙個包含 m × n 個格仔的面板,每乙個格仔都可以看成是乙個細胞。每個細胞具有乙個初始狀態 live(1)即為活細胞, 或 dead(0)即為死細胞。每個細胞與其八個相鄰位置(水平,垂直,對角線)的細胞都遵循以下四條生存定律:

根據當前狀態,寫乙個函式來計算面板上細胞的下乙個(一次更新後的)狀態。下乙個狀態是通過將上述規則同時應用於當前狀態下的每個細胞所形成的,其中細胞的出生和死亡是同時發生的。

示例1

輸入:

[ [0,1,0],

[0,0,1],

[1,1,1],

[0,0,0]

]輸出:

[ [0,0,0],

[1,0,1],

[0,1,1],

[0,1,0]

]

高階

這題要求你根據陣列每個元素四周的狀態來更新陣列元素。如果使用乙個輔助陣列,遍歷原陣列,然後儲存更新後的狀態到輔助陣列裡。這樣的話輕輕鬆鬆,沒有任何難度。但是這題意思是讓你不使用輔助陣列,直接修改原陣列元素,達到一樣的目的。

這樣的話就不能直接修改原陣列元素了,不然當你遍歷下乙個元素的時候,它周圍的值都變掉了,還怎麼看它要不要變呢?所以我們應該想辦法把變化前變化後的元素都儲存下來。

因為這題只有兩個狀態 0 和 1 ,所以我們可以用兩位二進位制來表示變化前和後的狀態,第一位表示變化後,第二位表示變化前。 00,10,01,11 分別表示 0 不變、0 變到 1 、1 變到 0 、1 不變四種變化情況。這樣的話就算你直接修改了元素值,也能獲取到它的原來的值。最後只需要進行第二遍掃瞄,取出變化後的值,也就是第一位就行了。

判斷和修改都可以通過位運算來完成。判斷修改前是否為 1 可以通過

而邊界問題很好處理,只需要判斷一下有沒有超出邊界就行了。

class

solution

;intdy

=;intn

=board

.size

(),m

=board[0

].size

();for

(intx=0;x

++x)}

if(board[x

][y]==

1)else}}

for(

intx=0

;x++x)}

}};

class

solution

:def

gameoflife

(self

,board

:list

[list

[int

]])->

none:dx

=[-1

,-1,

-1,0

,1,1

,1,0

]dy=[

-1,0

,1,1

,1,0

,-1,

-1]n

,m=len

(board

),len

(board[0

])forxin

range(n

):foryin

range(m

):cnt=0

fori

inrange(8

):nx,ny

=x+dx

[i],y

+dy[i

]if0<=

nx<

nand

0<=

ny<

mand

(board[nx

][ny]&

1)!=0

:cnt+=1

ifboard[x

][y]==

1:board[x

][y]+=

((1ifcnt==2

orcnt==3

else0)

<<1)

else

:board[x

][y]+=

((1ifcnt==3

else0)

<<1)

forx

inrange(n

):foryin

range(m

):board[x

][y]>>=

1

每日演算法系列 7

建立三個指標,分別指著head前乙個結點pre,head,head後乙個結點next。初始化pre,使得pre先指著位於鍊錶頭部外部空間,設為null,next也設為null但並不存在指向者。首先先將next指向head.next,用於儲存head的下乙個結點,使得鍊錶轉向不會因為鍊錶斷裂而丟失he...

每日演算法系列 LeetCode 376 擺動序列

如果連續數字之間的差嚴格地在正數和負數之間交替,則數字序列稱為擺動序列。第乙個差 如果存在的話 可能是正數或負數。少於兩個元素的序列也是擺動序列。例如,1,7,4,9,2,5 是乙個擺動序列,因為差值 6,3,5,7,3 是正負交替出現的。相反,1,4,7,2,5 和 1,7,4,5,5 不是擺動序...

每日演算法系列 LeetCode 386 字典序排數

給定乙個整數 n,返回從 1 到 n 的字典順序。例如,給定 n 13,返回 1,10,11,12,13,2,3,4,5,6,7,8,9 請盡可能的優化演算法的時間複雜度和空間複雜度。輸入的資料 n 小於等於 5,000,000。首先把 1 到 n 所有整數的字串形式放進陣列,然後對這個字串陣列進行...