52.腐烂的橘子
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
- 值 0 代表空单元格;
- 值 1 代表新鲜橘子;
- 值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。
示例1:

输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。
示例3:
输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 10
- grid[i][j] 仅为 0、1 或 2
代码:
1.BFS方案
class Solution {
//方向数组,分别代表上下左右四个方向横纵坐标的变化
int[][] dir = {{-1,0},{0,1},{1,0},{0,-1}};
//队列用于进行广度优先搜索,初始时存储每个腐烂橘子的横纵坐标
Queue<Pair<Integer,Integer> >q = new LinkedList<>();
//vis用于记录新鲜橘子腐烂所经过的最小分钟数
int[][] vis = new int[15][15];
public int orangesRotting(int[][] grid) {
//res存储最终结果
int res=0;
//m为网格的长
int m = grid.length;
//n为网格的宽
int n = grid[0].length;
////遍历网格存储初始时每个腐烂橘子的横纵坐标
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==2)q.add(new Pair<>(i,j));
}
}
//只要队列不空就继续处理
while(!q.isEmpty()){
//size为队列当前元素个数
int size = q.size();
//处理当前层所有元素
for(int i=0;i<size;i++){
//获取队列中当前元素坐标
Pair<Integer,Integer> t = q.remove();
int x = t.getKey();
int y = t.getValue();
////遍历四个方向
for(int j = 0;j<4;j++){
int x1 = x + dir[j][0];
int y1 = y + dir[j][1];
//如果当前位置未越界,而且当前位置的橘子为新鲜橘子
if(x1>=0&&x1<m&&y1>=0&&y1<n&&grid[x1][y1]==1){
//如果当前橘子未腐烂过或者当前橘子被腐烂过但是腐烂经过时间更长
if(vis[x1][y1]==0||vis[x1][y1]>vis[x][y]+1){
//更新当前橘子的腐烂时间
vis[x1][y1] = vis[x][y]+1;
//将当前元素坐标加入队列,继续递归
q.add(new Pair<>(x1,y1));
}
}
}
}
}
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++){
//如果当前橘子是新鲜橘子而且未腐烂过,则直接返回-1
if(grid[i][j]==1&&vis[i][j]==0)return -1;
//如果当前橘子被腐烂过,更新res
if(vis[i][j]!=0)res = Math.max(res,vis[i][j]);
}
}
//返回res
return res;
}
}
2.dfs方案
class Solution {
//vis用于记录新鲜橘子腐烂所经过的最小分钟数
int[][] vis = new int[15][15];
//方向数组,分别代表上下左右四个方向横纵坐标的变化
int[][] dir = {{-1,0},{0,1},{1,0},{0,-1}};
//list用来存储初始时每个腐烂橘子的横纵坐标
List<Pair<Integer,Integer> >list = new ArrayList<>();
public int orangesRotting(int[][] grid) {
//res存储最终结果
int res = 0;
//遍历网格存储初始时每个腐烂橘子的横纵坐标
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++){
if(grid[i][j]==2)list.add(new Pair<>(i,j));
}
}
//对每个腐烂橘子做dfs
for(Pair<Integer,Integer> p:list){
dfs(p.getKey(),p.getValue(),grid.length,grid[0].length,grid);
}
//遍历vis数组
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++){
//如果当前橘子是新鲜橘子而且未腐烂过,则直接返回-1
if(grid[i][j]==1&&vis[i][j]==0)return -1;
//如果当前橘子被腐烂过,更新res
if(vis[i][j]!=0)res = Math.max(res,vis[i][j]);
}
}
//返回res
return res;
}
public void dfs(int x,int y,int m,int n,int[][] grid){
//遍历四个方向
for(int i=0;i<4;i++){
int x1 = x+dir[i][0];
int y1 = y+dir[i][1];
//如果当前位置未越界,而且当前位置的橘子为新鲜橘子
if(x1>=0&&x1<m&&y1>=0&&y1<n&&grid[x1][y1]==1){
//如果当前橘子未腐烂过或者当前橘子被腐烂过但是腐烂经过时间更长
if(vis[x1][y1]==0||vis[x1][y1]>vis[x][y]+1){
//更新当前橘子的腐烂时间
vis[x1][y1] = vis[x][y]+1;
//继续递归
dfs(x1,y1,m,n,grid);
}
}
}
}
}

浙公网安备 33010602011771号