public class Solution {
public void gameOfLife(int[][] board) {
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
board[i][j] = nextState(board, i, j);
}
}
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(board[i][j] == 2 || board[i][j] == -2) board[i][j] = 1;
else board[i][j] = 0;
}
}
}
private int nextState(int[][] board, int row, int col){
int[] xDirs = {0, 0, 1, -1, 1, -1, -1, 1};
int[] yDirs = {1,-1, 0, 0, 1, -1, 1, -1};
int aliveCount = 0;
for(int i = 0; i < 8; i++){
int x = row + xDirs[i];
int y = col + yDirs[i];
// legal position
if(x >= 0 && x < board.length && y >= 0 && y < board[0].length){
if(board[x][y] > 0) aliveCount ++;
}
}
if(board[row][col] == 0){
if(aliveCount == 3) return -2;
else return -3;
} else {
if(aliveCount == 2 || aliveCount == 3) return 2;
else return 3;
}
}
}
和剥洋葱差不多,一层一层从外向里;我第一种写的多一点,但是更值得学习和更好推广的是第二种。
public class Solution {
public void rotate(int[][] matrix) {
if(matrix == null || matrix.length == 0) return;
int n = matrix.length;
for(int i = 0; i < n / 2; i++){
for(int j = i; j < n - i - 1; j++){
swap(matrix, i, j, j, n - 1 - i);
swap(matrix, i, j, n - 1 - i, n - 1 - j);
swap(matrix, i, j, n - 1 - j, i);
}
}
}
private void swap(int[][] matrix, int x1, int y1, int x2, int y2){
int tmp = matrix[x1][y1];
matrix[x1][y1] = matrix[x2][y2];
matrix[x2][y2] = tmp;
}
}
另一种更直观更好理解的方式是存两个指针,a , b , 分别代表着当前处理这层的 “左上” 和 “右下” 位置 (矩阵是正方形),然后 offset 和各种 index 就好计算很多,也完全不需要考虑到 base case 上时候的各种特殊情况。
public class Solution {
public void rotate(int[][] matrix) {
if(matrix == null || matrix.length == 0) return;
int n = matrix.length;
int a = 0;
int b = n - 1;
while(a < b){
for(int i = 0; i < (b - a); i++){
swap(matrix, a, a + i, a + i, b);
swap(matrix, a, a + i, b, b - i);
swap(matrix, a, a + i, b - i, a);
}
++a;
--b;
}
}
private void swap(int[][] matrix, int x1, int y1, int x2, int y2){
int tmp = matrix[x1][y1];
matrix[x1][y1] = matrix[x2][y2];
matrix[x2][y2] = tmp;
}
}