289. Game of Life

问题:

给定一个矩阵,1代表活,0代表死,进行下列转化,求所得矩阵

1.对于一个活节点,若周围8个cell,有小于2个活着,那么变死节点

2.对于一个活节点,若周围8个cell,有2或3个活着,那么保持活节点

3.对于一个活节点,若周围8个cell,有大于3个活着,那么变死节点

4.对于一个死节点,若周围8个cell,刚好有3个活着,那么重生为活节点

Example:
Input: 
[
  [0,1,0],
  [0,0,1],
  [1,1,1],
  [0,0,0]
]
Output: 
[
  [0,0,0],
  [1,0,1],
  [0,1,1],
  [0,1,0]
]

Follow up:
Could you solve it in-place? 
Remember that the board needs to be updated at the same time:
You cannot update some cells first and then use their updated values to update other cells. In this question, we represent the board using a 2D array. In principle, the board is infinite,
which would cause problems when the active area encroaches the border of the array. How would you address these problems?

  

解法方针:

求周围8个节点之和,可建立方向矩阵

1 vector<vector<int>> direct={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};

方法1:

不变化原矩阵,借助辅助矩阵 rem_verse 记录需要变化(即活->死,死->活)的节点位置即可。

最后遍历辅助矩阵,使用 异或 ^= 来变化矩阵。

代码参考:

 1 class Solution {
 2 public:
 3     void gameOfLife(vector<vector<int>>& board) {
 4         if(board.size()==0) return;
 5         int tmpsum=0;
 6         vector<vector<int>> rem_verse;
 7         int i=0, j=0, m=board[0].size(), n=board.size();
 8         vector<vector<int>> direct={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};
 9         for(i=0; i<n; i++){
10             for(j=0; j<m; j++){
11                 tmpsum=0;
12                 for(int k=0; k<8; k++){
13                     if(i+direct[k][0]<0 || i+direct[k][0]>=n || j+direct[k][1]<0 || j+direct[k][1]>=m) continue;
14                     tmpsum+=board[i+direct[k][0]][j+direct[k][1]];
15                 }
16                 if((tmpsum==3 && board[i][j]==0) || (tmpsum!=2 && tmpsum!=3 && board[i][j]==1)){
17                     rem_verse.push_back({i,j});
18                 }
19             }
20         }
21         for(int k=0; k<rem_verse.size(); k++){
22             board[rem_verse[k][0]][rem_verse[k][1]]^=1;
23         }
24     }
25 };

方法2:

不增加辅助矩阵,由于原矩阵只有0,1两种可能,可灵活使用高一位,来记录变化后的矩阵

最后遍历原矩阵,使用 右移1位,来获取记录的结果。

代码参考:

 1 class Solution {
 2 public:
 3     void gameOfLife(vector<vector<int>>& board) {
 4         if(board.size()==0) return;
 5         int tmpsum=0;
 6         int i=0, j=0, m=board[0].size(), n=board.size();
 7         vector<vector<int>> direct={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};
 8         for(i=0; i<n; i++){
 9             for(j=0; j<m; j++){
10                 tmpsum=0;
11                 for(int k=0; k<8; k++){
12                     if(i+direct[k][0]<0 || i+direct[k][0]>=n || j+direct[k][1]<0 || j+direct[k][1]>=m) continue;
13                     int tmp=board[i+direct[k][0]][j+direct[k][1]];
14                     tmpsum+=(tmp>1?tmp-2:tmp);
15                 }
16                 if(tmpsum==3 || (tmpsum==2 && board[i][j]==1)){
17                     board[i][j]+=2;
18                 }
19             }
20         }
21         for(i=0; i<n; i++){
22             for(j=0; j<m; j++){
23                 board[i][j]>>=1;
24             }
25         }
26     }
27 };
原文地址:https://www.cnblogs.com/habibah-chang/p/12678225.html