题目, 我觉得最简单的方法就是用四个for循环把他解出来,一个一个枚举,用两个矩阵进行保存
public class Main {
public void gameOfLife(int[][] board) {
int length = board.length;// 得到数组的长
int wide = board[0].length;// 得到数组的宽
int[][] temp = new int[length][wide];// 用于存放新的状态
for (int i = 0; i < length; i++) {//一个一个分情况看
for (int x = 0; x < wide; x++) {
int sum;
if (board[i][x] == 1) {
sum = -1;
} else
sum = 0;// 记录八个邻居有几个活细胞
for (int t1 = i - 1; t1 <= i + 1; t1++) {// for循环不能放太多if条件 不然会让程序出错
for (int t2 = x - 1; t2 <= x + 1; t2++) {
if (t1 > -1 && t1 < length) {//一开始将条件 放在for 循环里面,导致答案出错
if (t2 > -1 && t2 < wide) {
if (board[t1][t2] != 0) {
sum++;
}
}
}
}
}
if (sum < 2) {//条件分析
temp[i][x] = 0;
} else if (sum == 2) {
temp[i][x] = board[i][x];
} else if (sum == 3) {
temp[i][x] = 1;
} else if (sum > 3) {
temp[i][x] = 0;
}
}
}
for (int i = 0; i < length; i++) {//一个一个读回去
for (int x = 0; x < wide; x++) {
board[i][x] = temp[i][x];
}
}
}
public static void main(String[] args) {//测试用例
Main m = new Main();
int arr[][] = { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 0 } };
m.gameOfLife(arr);
for (int i = 0; i < arr.length; i++) {
for (int x = 0; x < arr[0].length; x++) {
System.out.print(arr[i][x]);
}
System.out.println();
}
}
}
其他人的解法
class Solution {
//第一遍遍历,将1并且周围有两个或三个1的位置设为-1,-1表示这个位置细胞是死的,先设为-1,后面再设为0
//第二遍遍历,将0并且周围有三个1的位置设为2,2表示这个位置细胞是活的,先设为2,后面再设为1
//第三遍遍历,将所有-1设为0,所有2设为1
//计算周围活着的细胞个数时,取1或-1的绝对值
//将值换的话 需要不影响其他值 ,该解法也做到这一点 将值替换成其他数
public void gameOfLife(int[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
int count = count(board, i, j);
if (board[i][j] == 1 && count != 2 && count != 3) {
board[i][j] = -1;
}
}
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
int count = count(board, i, j);
if (board[i][j] == 0 && count == 3) {
board[i][j] = 2;
}
}
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == -1) {
board[i][j] = 0;
}else if(board[i][j] == 2) {
board[i][j] = 1;
}
}
}
}
private int count(int[][] board, int row, int col) {统计周围有几个活细胞
int liveAround = 0;
int rowMax = row + 1 > board.length - 1 ? board.length - 1 : row + 1;
int colMax = col + 1 > board[0].length - 1 ? board[0].length - 1 : col + 1;
int rowMin = row - 1 < 0 ? 0 : row - 1;
int colMin = col - 1 < 0 ? 0 : col - 1;
for (int i = rowMin; i >= 0 && i <= rowMax; i++) {
for (int j = colMin; j >= 0 && j <= colMax; j++) {
if (!(row == i && col == j) && Math.abs(board[i][j]) == 1) {
liveAround++;
}
}
}
return liveAround;
}
}
public void gameOfLife(int[][] board) {
if (board == null || board.length == 0) return;
int m = board.length, n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int lives = liveNeighbors(board, m, n, i, j);
// In the beginning, every 2nd bit is 0;
// So we only need to care about when will the 2nd bit become 1.
if (board[i][j] == 1 && lives >= 2 && lives <= 3) {
board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11
}
if (board[i][j] == 0 && lives == 3) {
board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
board[i][j] >>= 1; // Get the 2nd state.
}
}
}
public int liveNeighbors(int[][] board, int m, int n, int i, int j) {
int lives = 0;
for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) {
for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {
lives += board[x][y] & 1;
}
}
lives -= board[i][j] & 1;
return lives;
}