From aaa32a3f462cffbb82f8f671de724dd93e6d5417 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Thu, 7 Nov 2019 20:47:51 +0800 Subject: [PATCH] Create 289. Game of Life.md --- solutions/289. Game of Life.md | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 solutions/289. Game of Life.md diff --git a/solutions/289. Game of Life.md b/solutions/289. Game of Life.md new file mode 100644 index 0000000..3a41937 --- /dev/null +++ b/solutions/289. Game of Life.md @@ -0,0 +1,64 @@ +# [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; + } + } +}; +```