题目
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
思路
就利用一个广搜,必须是要腐烂橘子去感染新鲜橘子,先统计出来新鲜橘子的个数,每次广搜到可以感染的,就减一。等到队列为空了,看看新鲜橘子是否被感染完了,如果感染完了,则返回最慢感染的数值,否则返回-1。可以开又一个搜索类型,记录下当前橘子的横坐标,纵坐标,还有被污染的时间(当然前提是可以被污染)。每次从队头取出一个腐烂的橘子,看看它当前被污染的时间,如果大于目前记录的,就更新当前时间,最终搜索完成,就可以得到最终的结果!
代码
import java.util.LinkedList;
import java.util.Queue;
class Orange{
int x;
int y;
int time; // 经过多长时间被感染为腐烂的橘子
public Orange (int x,int y,int time)
{
this.x=x;
this.y=y;
this.time=time;
}
}
class Solution {
int map[][]=new int[10][10];
int visited[][]=new int[10][10];
int row;
int column;
Queue<Orange> queue = new LinkedList<>();
int ans = -1;
int direction[][]={{0,1},{0,-1},{1,0},{-1,0}};
public int orangesRotting(int[][] grid)
{
queue.clear();
int FreshOrange=0;
row=grid.length;
column=grid[0].length;
for (int i=0;i<row;++i)
{
for (int j=0;j<column;++j)
{
map[i][j]=grid[i][j]; // 赋值为全局地图
visited[i][j]=0; // 初始化,没走过
if (grid[i][j]==1)
{
++FreshOrange;
}
else if (grid[i][j]==2)
{
queue.add(new Orange(i,j,0));
}
}
}
// 0分钟就已经没有新鲜橘子了,规避掉没有新鲜橘子的情况
if (FreshOrange==0)
{
return 0;
}
while (!queue.isEmpty())
{
Orange temp= queue.poll();
int t_x = 0;
int t_y = 0;
if (temp.time>ans)
{
ans=temp.time;
}
for (int i=0;i<4;++i)
{
t_x = temp.x + direction[i][0];
t_y = temp.y + direction[i][1];
if (check(t_x,t_y))
{
queue.add(new Orange(t_x,t_y,temp.time+1));
map[t_x][t_y]=2;
visited[t_x][t_y]=1;
--FreshOrange;
}
}
}
return FreshOrange==0?ans:-1;
}
public boolean check(int t_x, int t_y)
{
// 横坐标不越界 纵坐标不越界 是新鲜橘子 没有被访问过
return t_x>=0 && t_x<row && t_y >=0 && t_y <column && map[t_x][t_y]==1 && visited[t_x][t_y]==0;
}
}
结果
简单广搜题,不过因为自己写错了一个条件,卡了很久,以后写代码的时候,脑子要清晰一点!