问题:
给定一个矩阵,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 };