题意
给定一个生命游戏的当前状态,修改为下一个状态。
当前状态由一个m*n的二维数组board决定,其中1代表对应的细胞死亡,0代表对应的细胞存活。
每个细胞的下一个状态由其附近的8个细胞的当前状态决定:
任何活细胞周围的活细胞数不足2个时,会死亡
任何活细胞周围的活细胞数为2或3个时,会保持存活
任何活细胞周围的活细胞数超过3个时,会死亡
任何死细胞周围的活细胞数为3个时,会复活变成存活状态
数据限制
m==board.length
n==board[i].length
1=m,n=25
board[i][j]是0或1
样例
思路:模拟+状态压缩
我们可以使用两位二进制位来表示每个细胞的当前状态和下一个状态:
最低位表示当前状态,state1为1表示当前状态为存活,state1为0表示当前状态为死亡;
次低位表示下一个状态,state2为2表示下一个状态为存活,state2为0表示下一个状态为死亡。
然后我们枚举每一个细胞,统计其周围的当前存活细胞数,再根据生命游戏的规则,更新其下一个状态。
最后我们再将每个细胞的下一个状态转为当前状态。
时间复杂度:O(m*n)
需要遍历board中全部O(m*n)个细胞
空间复杂度:O(1)
只需要维护常数个额外变量
代码(Python3)
#8个方向的位置改变量DIRS:List[Tuple[int,int]]=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]classSolution:defgameOfLife(self,board:List[List[int]])-None:"""Donotreturnanything,modifyboardin-placeinstead."""m:int=len(board)n:int=len(board[0])#枚举每一个细胞forrinrange(m):forcinrange(n):#统计当前细胞周围的存活细胞数liveCells:int=0fordr,dcinDIRS:#计算对应方向的细胞的行列号rr:int=r+drcc:int=c+dc#如果未越界,且对应细胞的当前状态是存活,#则liveCells加1if0=rrmand0=ccn:liveCells+=board[rr][cc]1#下一个状态为存活需要满足以下任意条件:#1.周围有3个存活细胞#2.当前是活细胞,且周围有2个活细胞ifliveCells==3or(board[r][c]==1andliveCells==2):board[r][c]
=2#将每个细胞的下一个状态转为当前状态forrinrange(m):forcinrange(n):board[r][c]=1
代码(Go)
//个方向的位置改变量vardr=[]int{-1,-1,0,1,1,1,0,-1};vardc=[]int{0,1,1,1,0,-1,-1,-1};funcgameOfLife(board[][]int){m:=len(board)n:=len(board[0])//枚举每一个细胞forr:=0;rm;r++{forc:=0;cn;c++{//统计当前细胞周围的存活细胞数liveCells:=0fori:=0;i8;i++{//计算对应方向的细胞的行列号rr:=r+dr[i]cc:=c+dc[i]//如果未越界,且对应细胞的当前状态是存活,//则liveCells加1if0=rrrrm0=ccccn{liveCells+=board[rr][cc]1}}//下一个状态为存活需要满足以下任意条件://1.周围有3个存活细胞//2.当前是活细胞,且周围有2个活细胞ifliveCells==3
(board[r][c]==1liveCells==2){board[r][c]
=2}}}//将每个细胞的下一个状态转为当前状态forr:=0;rm;r++{forc:=0;cn;c++{board[r][c]=1}}}
题目链接:
GameofLife: