According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."html
Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):git
Write a function to compute the next state (after one update) of the board given its current state. The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously.github
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:app
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.post
這道題是有名的 康威生命遊戲, 而我又是第一次據說這個東東,這是一種細胞自動機,每個位置有兩種狀態,1爲活細胞,0爲死細胞,對於每一個位置都知足以下的條件:this
1. 若是活細胞周圍八個位置的活細胞數少於兩個,則該位置活細胞死亡url
2. 若是活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活spa
3. 若是活細胞周圍八個位置有超過三個活細胞,則該位置活細胞死亡code
4. 若是死細胞周圍正好有三個活細胞,則該位置死細胞復活
因爲題目中要求用置換方法 in-place 來解題,因此就不能新建一個相同大小的數組,那麼只能更新原有數組,題目中要求全部的位置必須被同時更新,但在循環程序中仍是一個位置一個位置更新的,當一個位置更新了,這個位置成爲其餘位置的 neighbor 時,怎麼知道其未更新的狀態呢?能夠使用狀態機轉換:
狀態0: 死細胞轉爲死細胞
狀態1: 活細胞轉爲活細胞
狀態2: 活細胞轉爲死細胞
狀態3: 死細胞轉爲活細胞
最後對全部狀態對2取餘,則狀態0和2就變成死細胞,狀態1和3就是活細胞,達成目的。先對原數組進行逐個掃描,對於每個位置,掃描其周圍八個位置,若是遇到狀態1或2,就計數器累加1,掃完8個鄰居,若是少於兩個活細胞或者大於三個活細胞,並且當前位置是活細胞的話,標記狀態2,若是正好有三個活細胞且當前是死細胞的話,標記狀態3。完成一遍掃描後再對數據掃描一遍,對2取餘變成咱們想要的結果。參見代碼以下:
class Solution { public: void gameOfLife(vector<vector<int> >& board) { int m = board.size(), n = m ? board[0].size() : 0; vector<int> dx{-1, -1, -1, 0, 1, 1, 1, 0}; vector<int> dy{-1, 0, 1, 1, 1, 0, -1, -1}; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { int cnt = 0; for (int k = 0; k < 8; ++k) { int x = i + dx[k], y = j + dy[k]; if (x >= 0 && x < m && y >= 0 && y < n && (board[x][y] == 1 || board[x][y] == 2)) { ++cnt; } } if (board[i][j] && (cnt < 2 || cnt > 3)) board[i][j] = 2; else if (!board[i][j] && cnt == 3) board[i][j] = 3; } } for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { board[i][j] %= 2; } } } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/289
相似題目:
參考資料:
https://leetcode.com/problems/game-of-life/
https://leetcode.com/problems/game-of-life/discuss/73217/Infinite-board-solution
https://leetcode.com/problems/game-of-life/discuss/73230/C%2B%2B-O(1)-space-O(mn)-time
https://leetcode.com/problems/game-of-life/discuss/73223/Easiest-JAVA-solution-with-explanation