298. 生命游戏
难度:中等
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
执行用时 : 2 ms, 在Game of Life的Java提交中击败了65.98% 的用户
内存消耗 : 34.4 MB, 在Game of Life的Java提交中击败了94.07% 的用户
Code:
class Solution {
public void gameOfLife(int[][] board) {
int[][] dir = { //相邻8格子
{-1,-1},{-1,0}, {-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
for(int i=0;i<board.length;++i){
for(int j=0;j<board[0].length;++j){
int total=0;//计算周围活细胞数量
for(int k=0;k<dir.length;++k){
if(i+dir[k][0]>=0&&i+dir[k][0]<board.length&&j+dir[k][1]>=0&&j+dir[k][1]<board[0].length){//边界判断
if(board[i+dir[k][0]][j+dir[k][1]]==1||board[i+dir[k][0]][j+dir[k][1]]==-1)
total++;
}
}
if(board[i][j]==1&&(total<2||total>3))
board[i][j]=-1; //活细胞->死细胞,值暂改为-1
else if(board[i][j]==0&&total==3)
board[i][j]=2; //死细胞->活细胞,值暂改为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;
}
}
}
}
980. 不同路径 III
难度:困难
在二维网格 grid 上,有 4 种类型的方格:
1 表示起始方格。且只有一个起始方格。
2 表示结束方格,且只有一个结束方格。
0 表示我们可以走过的空方格。
-1 表示我们无法跨越的障碍。
返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目,每一个无障碍方格都要通过一次。
示例 1:
输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
示例 1:
输入:[[0,1],[2,0]]
输出:0
解释:
没有一条路能完全穿过每一个空的方格一次。
请注意,起始和结束方格可以位于网格中的任意位置。
执行用时 : 1 ms, 在Unique Paths III的Java提交中击败了100.00% 的用户
内存消耗 : 34.6 MB, 在Unique Paths III的Java提交中击败了69.64% 的用户
思路:dfs
Code:
class Solution {
int zeros=0;//0个数
int result=0;//结果
public int uniquePathsIII(int[][] grid) {
//起点
int stx=0;
int sty=0;
for(int i=0;i<grid.length;++i){
for(int j=0;j<grid[0].length;++j)
{
if(grid[i][j]==1){
stx=i;
sty=j;
}
else if(grid[i][j]==0)
zeros++;
}
}
dfs(stx,sty,grid,0);
return result;
}
public void dfs(int stx,int sty,int[][] grid,int steps){
if (grid[stx][sty] == 2){//终点,判断是否全部遍历
if(steps==zeros+1)
result++;
return;
}
if(grid[stx][sty]==-1||grid[stx][sty]==3)//遇到障碍或重复走
return;
grid[stx][sty]=3;//走过的格子设置为3
int tmp;
//四个方向
if(stx>0){
tmp = grid[stx-1][sty];
dfs(stx-1,sty,grid,steps+1);
grid[stx-1][sty] = tmp; //回溯时恢复原值
}
if(sty>0){
tmp = grid[stx][sty-1];
dfs(stx,sty-1,grid,steps+1);
grid[stx][sty-1] = tmp;
}
if(stx<grid.length-1){
tmp = grid[stx+1][sty];
dfs(stx+1,sty,grid,steps+1);
grid[stx+1][sty] = tmp;
}
if(sty<grid[0].length-1){
tmp = grid[stx][sty+1];
dfs(stx,sty+1,grid,steps+1);
grid[stx][sty+1] = tmp;
}
}
}