腐烂的橘子
题目
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
示例 1:
image
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:
输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:
输入:[[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j] 仅为 0、1 或 2
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotting-oranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
参照leetcode官方解答有以下领悟:
这种图的题目就是遍历问题,是广度优先搜索.可以先将所有初始的腐烂橘子放入队列,然后依次从队列中取出腐烂橘子,判断腐烂橘子方便的橘子,依次变腐烂.最后判断是否还有新鲜橘子.具体可能还是看代码容易理解一些.在比较腐烂橘子的四周时,官方的题解有些没有懂,所以我使用了很好理解的方式.
代码
class Solution {
class Position{
private Integer x;
private Integer y;
private Integer time;
public Position(Integer x,Integer y,Integer time){
this.x = x;
this.y = y;
this.time = time;
}
}
public int orangesRotting(int[][] grid) {
//首先腐烂橘子的位置需要确定
//其次需要确定有无周围没有橘子存在的单独橘子,如果有,则可以直接返回-1
//大概的想法是先找到腐烂橘子,然后将腐烂橘子周围的橘子入队,并依次向后入队.最后查找是否还有无新鲜橘子即可判断.
Queue<Position> queue = new LinkedList<>();
int time = 0;
//先找初始的腐烂橘子的位置
for(int i = 0;i < grid.length;i++){
for(int j = 0;j < grid[i].length;j++){
if(grid[i][j] == 2){
Position position = new Position(i,j,time);
queue.add(position);
}
}
}
//依次将原有队列出队,然后判断当前节点的四周是否有新鲜橘子,如果有,则将其入队.循环往复
while(!queue.isEmpty()){
Position position = queue.poll();
//对应的四个坐标分别是x-1,y,x+1,y,x,y-1,x,y+1
time = position.time+1;
boolean timeChange = false;
if(position.x-1 >=0 && grid[position.x-1][position.y] == 1){
grid[position.x-1][position.y] = 2;
queue.add(new Position(position.x-1,position.y,time));
timeChange = true;
}
if(position.x+1 <=grid.length-1 && grid[position.x+1][position.y] == 1){
grid[position.x+1][position.y] = 2;
queue.add(new Position(position.x+1,position.y,time));
timeChange = true;
}
if(position.y-1 >=0 && grid[position.x][position.y-1] == 1){
grid[position.x][position.y-1] = 2;
queue.add(new Position(position.x,position.y-1,time));
timeChange = true;
}
if(position.y+1 <=grid[position.x].length-1 && grid[position.x][position.y+1] == 1){
grid[position.x][position.y+1] = 2;
queue.add(new Position(position.x,position.y+1,time));
timeChange = true;
}
if (!timeChange){
time--;
}
timeChange = false;
}
//遍历原有集合,判断是否还有新鲜橘子
for(int i = 0;i < grid.length;i++){
for(int j = 0;j < grid[i].length;j++){
if(grid[i][j] == 1){
return -1;
}
}
}
return time;
}
}