这道题要求能考虑在原地算法解决本题,请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
这样的话我们就必须先定义一下标准,标记哪些位置该改变,而哪些位置不需要变化。
我们可以这样设计一个模拟:
0:死细胞转为死细胞
1:活细胞转为活细胞
2:活细胞转为死细胞
3:死细胞转为活细胞
之后呢,我们就可以依据该位置的值来进行死活细胞转换,下面是代码
class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
int m = board.size();
int n = board[0].size();
// 方向数组,用于遍历八个方向
vector<int> dx = {-1, -1, -1, 0, 0, 1, 1, 1};
vector<int> dy = {-1, 0, 1, -1, 1, -1, 0, 1};
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int liveNeighbors = 0;
// 计算活邻居的数量
for (int k = 0; k < 8; ++k) {
int ni = i + dx[k];
int nj = j + dy[k];
if (ni >= 0 && ni < m && nj >= 0 && nj < n && (board[ni][nj] == 1 || board[ni][nj] == 2)) {
++liveNeighbors;
}
}
// 根据规则更新状态
if (board[i][j] == 1) {
if (liveNeighbors < 2 || liveNeighbors > 3) {
board[i][j] = 2; // 活细胞转为死细胞
}
} else {
if (liveNeighbors == 3) {
board[i][j] = 3; // 死细胞转为活细胞
}
}
}
}
// 将状态转换回0和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] == 3) {
board[i][j] = 1;
}
}
}
}
};
解释
- 状态编码:用
2
表示活细胞转死,用3
表示死细胞转活。 - 邻居计算:使用方向数组计算每个细胞的活邻居数时,检查
1
和2
状态。 - 状态更新:根据邻居数更新细胞的状态,但不立即改变
0
和1
,而是用2
和3
表示过渡状态。 - 最终转换:遍历整个面板,将
2
转为0
,3
转为1
,得到下一个状态。