# [289. Game of Life](https://leetcode.com/problems/game-of-life/) # 思路 给定一个二维数组每个元素代表一个细胞,元素的值代表细胞当前的死活,1为活细胞,0为死细胞,要求下一时刻所有细胞的死活状态。 细胞的下一个时刻的死活由如下条件决定: 1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞下一时刻死亡; 2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞下一时刻仍然存活; 3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞下一时刻死亡; 4. 如果死细胞周围正好有三个活细胞,则该位置死细胞下一时刻复活; 由于题目中要求in-place,所以就不能新建一个相同大小的数组,那么只能更新原有数组,但是我们不能直接更新到下一时刻的状态, 所以我们可以考虑更新到一个中间态,这个中间态可以随意定义,只要能区分开来就可以了,例子如下: ||当前状态|下一状态|中间状态| | :-: | :-: | :-: | :-: | |情形一| 0 | 0 | 0 | |情形二| 0 | 1 | -1 | |情形三| 1 | 0 | 2 | |情形四| 1 | 1 | 1 | 最后需要再遍历一遍把中间态改为最终态。 时间复杂度O(n),线性复杂度O(1) # C++ ``` C++ class Solution { const int dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; const int dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; int m, n; private: int live_nbs(vector>& board, int i, int j){ int count = 0, nx, ny; for(int k = 0; k < 8; k++){ nx = i + dx[k]; ny = j + dy[k]; if(nx >= 0 && nx < m && ny >= 0 && ny < n && board[nx][ny] > 0) count++; } return count; } public: void gameOfLife(vector>& board) { // 00 0, 01 -1, 10 2, 11 1 m = board.size(); n = board[0].size(); for(int i = 0; i < m; i++) for(int j = 0; j < n; j++){ int count = live_nbs(board, i, j); if(board[i][j]){ if(count < 2 || count > 3) board[i][j] = 2; } else if(count == 3) board[i][j] = -1; } for(int i = 0; i < m; i++) for(int j = 0; j < n; j++){ if(board[i][j] == 2) board[i][j] = 0; else if(board[i][j] == -1) board[i][j] = 1; } } }; ```