LeetCode 289. Game of Life (State Synchronization)

Insert picture description here

Ideas:

  • The main difficulty of this question is that if you update the original array directly according to the rules, then the synchronous update mentioned in the question cannot be done. Suppose you directly fill the updated cell state into the original array, then the update of other cell states in the current round will refer to the state of the updated cell in the current round, but in fact each round of update depends on the state of the previous round of cells , Cannot be updated with this round of cell state.
  • Of course, we can solve the above problem by copying an additional array, but if we want to solve it directly in situ, we can also use bit operations.
  • The original live cell can be regarded as ob01, and the dead cell can be regarded as ob00, so when the live cell is still alive, we can change the original value to ob11, if it becomes a dead cell, do not modify the original value; The value is modified to ob10 when dead cells become live cells, and the value is not modified when dead cells remain unchanged.
  • Finally, we just need to move the value of each cell to the right by one bit and it's done.

Code:

class Solution {
    
    
public:
    int DX[8] = {
    
    0, 0, 1, -1, 1, 1, -1, -1};
    int DY[8] = {
    
    1, -1, 0, 0, 1, -1, 1, -1};
    void gameOfLife(vector<vector<int>>& board) {
    
    
          if (board.size() == 0) {
    
    
            return;
        }
        int n = board.size();
        int m = board[0].size();
        for (int i = 0; i < n; ++i) {
    
    
            for (int j = 0; j < m; ++j) {
    
    
                int cnt = 0;
                for (int k = 0; k < 8; k++) {
    
    
                    int x = i + DX[k];
                    int y = j + DY[k];
                    if (x < 0 || x >=n || y < 0 || y >=m) {
    
    
                        continue;
                    }
                    // 这里不能直接加board[x][y],因为 board[x][y] 的倒数第二位是可能有值的。
                    cnt += board[x][y] & 1;
                }
                if ((board[i][j] & 1) > 0) {
    
    
                    // 这个是活细胞
                    if (cnt >= 2 && cnt <= 3) {
    
    
                        // 周围有2/3个活细胞,下一个状态还是活细胞。
                        board[i][j] = 0b11;
                    }
                    // 周围活细胞过多或过少都会死,因为原数据是0b01,所以这里不用额外赋值。
                } else if (cnt == 3) {
    
    
                    // 这个是死细胞,周围有3个活细胞,下一个状态变为活细胞。
                    board[i][j] = 0b10;
                }
            }
        }
        // 最后一位去掉,倒数第二位变为更新后的状态。
        for (int i = 0; i < n; i++) {
    
    
            for (int j = 0; j < m; j++) {
    
    
                board[i][j] >>= 1;
            }
        }
    }
};

Guess you like

Origin blog.csdn.net/qq_43663263/article/details/108069647