github仓库:https://github.com/lzed/leetcode
题意
给出一个矩阵的一个状态,根据一定规则来计算下一个状态。
思路
算法1
O(mn) 的额外空间。
新开一个数组来获得下一个状态即可,这样可以保证状态互不干扰。
算法2
O(1) 额外空间, O(mn) 时间。
要更新一个位置 (i,j) 的时候,我们需要知道它的neibor的状态,但是neibor的状态可能已经被更新过,但是我们依赖的是以前的状态,然后最后的结果统计又依赖于最后的状态。即又依赖于之前的状态,又依赖于之后的状态,那么我们就可以建立一个状态转化的映射:
f(x,y)=s :分别代表之前状态是x,转化为一个新的状态y,我们用s代表其接结果。
那么,一共只有4种转化(1代表Live,0代表dead)
f(0,0)=2
f(0,1)=3
f(1,0)=4
f(1,1)=5
于是,在对 (i,j) 进行状态更新时,我们可以通过上面的转换表得到它周围的更新/未更新位置的初始状态。
最后统计结果的时候,我们再对上述关系进行逆映射来得到最后结果。
代码
algorithm 1
class Solution {
public:
int judge(int x, int y, vector<vector<int>>& a) {
int cnt = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (!i && !j) continue;
int nx = x + i, ny = y + j;
if (nx >= 0 && nx < a.size() && ny >= 0 && ny < a[0].size()) {
if (a[nx][ny]) cnt++;
}
}
}
return cnt;
}
void gameOfLife(vector<vector<int>>& board) {
int m = board.size();
if (m) {
int n = board[0].size();
vector<vector<int>> a(board.size(), vector<int>(n));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int t = judge(i, j, board);
if (board[i][j]) {
if (t < 2) a[i][j] = 0;
else if (t == 2 || t == 3) a[i][j] = 1;
else a[i][j] = 0;
} else {
if (t == 3) a[i][j] = 1;
else a[i][j] = 0;
}
}
}
board = a;
}
}
};
algorithm 2
class Solution {
public:
int f(int x, int y) {
if (!x && !y) return 2;
if (!x && y) return 3;
if (x && !y) return 4;
return 5;
}
int g_pre(int s) {
if (s == 1 || s == 0) return s;
if (s == 2 || s == 3) return 0;
return 1;
}
int g_now(int s) {
if (s == 1 || s == 0) return s;
if (s == 2 || s == 4) return 0;
return 1;
}
int judge(int x, int y, vector<vector<int>>& a) {
int cnt = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (!i && !j) continue;
int nx = x + i, ny = y + j;
if (nx >= 0 && nx < a.size() && ny >= 0 && ny < a[0].size()) {
if (g_pre(a[nx][ny])) cnt++;
}
}
}
return cnt;
}
void gameOfLife(vector<vector<int>>& board) {
int m = board.size();
if (m) {
int n = board[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int t = judge(i, j, board);
if (board[i][j]) {
if (t < 2 || t >= 4) board[i][j] = f(1, 0);
else board[i][j] = f(1, 1);
} else {
if (t == 3) board[i][j] = f(0, 1);
else board[i][j] = f(0, 0);
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
board[i][j] = g_now(board[i][j]);
}
}
}
};