题目:
According to the Wikipedia'sarticle: "The Game of Life, alsoknown simply as Life, is a cellularautomaton devised by the British mathematician John Horton Conway in1970."
Given a board with m by ncells, each cell has an initial state live(1) or dead (0). Each cell interactswith its eightneighbors (horizontal, vertical, diagonal) using the following four rules(taken from the above Wikipedia article):
- Any live cell with fewer than two live neighbors dies, as if caused by under-population.
- Any live cell with two or three live neighbors lives on to the next generation.
- Any live cell with more than three live neighbors dies, as if by over-population..
- Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
Write a function to compute the next state (after one update) ofthe board given its current state.
要求:
- 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?
原先的想法是每一次读到一个点,就检查周围的所有点,但是这样不能满足题目的要求,而且时间复杂度较高。于是,参考网上的代码,以下为摘抄:
由于题目中要求所有点的状态需要一次性发生改变,而且不用额外的空间,这是本题的最大难点。
既然需要“就地解决”,我们不妨分析一下borad的特性:board上的元素有两种状态,生(1)和死(0)。这两种状态存在了一个int型里面。所以我们可以有效利用除最低位的其它位,去保存更新后的状态,这样就不需要有额外的空间了。
具体而言,我们可以用最低位表示当前状态,次低位表示更新后状态:
- 00(0):表示当前是死,更新后是死;
- 01(1):表示当前是生,更新后是死;
- 10(2):表示当前是死,更新后是生;
- 11(3):表示当前是神,更新后是生。
提交代码:
class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
int row = board.size();
int column = board[0].size();
if(row == 0 || column == 0) return;
for(int x = 0; x < row; x++) {
for(int y = 0; y < column; y++) {
int life = getlive(board, row, column, x, y);
if(board[x][y] == 1 && (life == 2 || life == 3))
board[x][y] = 3;
if(board[x][y] == 0 && life == 3)
board[x][y] = 2;
}
}
for(int x = 0; x < row; x++) {
for(int y = 0; y < column; y++) {
board[x][y] >>= 1;
}
}
}
private:
int getlive(vector<vector<int>>& board, int row, int column, int x, int y) {
int num = 0;
for(int i = max(x - 1, 0); i < min(x + 2, row); i++) {
for(int j = max(y - 1, 0); j < min(y + 2, column); j++) {
if(i == x && j == y) continue;
else if(board[i][j] % 2 == 1) num++;
}
}
return num;
}
};
其中min容易出现越界,应该注意。
应用网址:
http://www.cnblogs.com/jdneo/p/5236373.html