118 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* https://leetcode.cn/problems/game-of-life/?envType=study-plan-v2&envId=top-interview-150
* @param {number[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
const gameOfLife = function (board) {
};
/*
模拟按照题目要求模拟遍历所有的细胞通过细胞周围的8个细胞来判断它下一次更新的状态细胞的状态由下面的条件决定
1.细胞是活的会有三种情况如果周围活细胞数量小于2那么这个细胞死亡如果周围活细胞数量为2个或3个那么这个细胞维持
存活状态,如果这个细胞周围的活细胞超过了三个,那么这个细胞死亡.
2.细胞是死的,如果周围正好有三个活细胞那么就复活这个细胞。
按照上面的要求我们可以把问题拆分为这样,如果这个细胞是活的 并且周围的活细胞少于两个,或者周围的活细胞大于三个,那么这个细胞死亡;
如果这个细胞是死的,周围正好有三个活细胞,那么就复活这个细胞
*/
function f1(board) {
const m = board.length - 1;
const n = board[0].length - 1;
let lives = 0; // 表示当前细胞周围的活细胞数量
const updates = []; // 细胞下一次要更新的状态
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
// 查看左上角的细胞是否存活
if (i > 0 && j > 0 && board[i - 1][j - 1] === 1) lives++;
// 查看上面的细胞是否存活
if (i > 0 && board[i - 1][j] === 1) lives++;
// 查看右上角的细胞是否存活
if (i > 0 && j < n && board[i - 1][j + 1] === 1) lives++;
// 查看右边的细胞是否存活
if (j < n && board[i][j + 1] === 1) lives++;
// 查看右下角的细胞是否存活
if (i < m && j < n && board[i + 1][j + 1] === 1) lives++;
// 查看下面的细胞是否存活
if (i < m && board[i + 1][j] === 1) lives++;
// 查看左下角的细胞是否存活
if (i < m && j > 0 && board[i + 1][j - 1] === lives) lives++;
// 查看左边的细胞是否存活
if (j > 0 && board[i][j - 1] === 1) lives++;
// 如果当前细胞是活的,只要它周围存活的细胞小于二,或者大于三,那么下一次更新的状态是死亡,把更新状态存入更新数组
if (board[i][j] === 1 && (lives < 2 || lives > 3)) {
updates.push(0);
continue;
}
// 如果当前细胞是死的, 只要周围存活的细胞恰好等于3,那么下次更新的状态就是复活,把更新状态存入更新数组
if (board[i][j] === 0 && lives === 3) {
updates.push(1);
continue;
}
// 如果细胞状态无需变化往更新数组插入数据-1,表示无需更新
updates.push(-1);
}
}
// 通过updates更新数组来更新整个board
let k = 0;
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
if (updates[k] >= 0) board[i][j] = updates[k];
k++;
}
}
}
/*
利用次低位来保存下一次更新的状态省去了updates更新数组的空间
*/
function f2(board) {
const dx = [-1, 0, 1, -1, 1, -1, 0, 1];
const dy = [-1, -1, -1, 0, 0, 1, 1, 1];
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[0].length; j++) {
let sum = 0;
// 计算周围8个邻居的活细胞数
for (let k = 0; k < 8; k++) {
const nx = i + dx[k];
const ny = j + dy[k];
if (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length) {
sum += (board[nx][ny] & 1); // 累加邻居细胞的最低位(表示当前活或死)
}
}
// // 根据规则设置细胞的未来状态
// if (board[i][j] === 1) {
// // 如果当前细胞是活的
// if (sum === 2 || sum === 3) {
// board[i][j] |= 2; // 设次低位为1表示细胞将在下一轮继续存活
// }
// } else {
// // 如果当前细胞是死的
// if (sum === 3) {
// board[i][j] |= 2; // 设次低位为1表示细胞将在下一轮复活
// }
// }
// 根据规则设置细胞的未来状态
if (sum === 3 || (board[i][j] === 1 && (sum === 2 || sum === 3))) {
board[i][j] |= 2; // 设次低位为1表示细胞将在下一轮存活或复活
}
}
}
// 第二次遍历,更新细胞的状态
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
board[i][j] >>= 1; // 右移1位更新状态为新的细胞状态
}
}
}