在给定的 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
题意
求出让所有橘子都腐败的时间
思路
因为每个腐败橘子都会传染周围的橘子,同时每个腐败橘子都是一起传染周围,所以我们直接就想到用优先队列了。起始我们把腐败橘子都记录下来,并且标记一下距离d[i][j]=0,然后加入队列,接着就可以直接遍历队列套模板了。
代码如下
class Solution {
public:
int dx[4]={-1,0,1,0}; //四个方向
int dy[4]={0,-1,0,1}; //四个方向
struct node{
int dis; //距离
int x,y; //坐标
bool operator <(const node &W)const{ //自定义排序
return dis>W.dis;
}
};
int orangesRotting(vector<vector<int>>& g) {
int n=g.size(),m=g[0].size();
vector<vector<int>> d(n,vector<int>(m,-1));
priority_queue<node> q; //定义小根堆,因为前面node结构体已经自定义排序了
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(g[i][j]==2)
{
q.push({0,i,j});
d[i][j]=0;
}
while(q.size()){
auto t = q.top();
q.pop();
int dis = t.dis;
int tx = t.x,ty=t.y;
//cout<<tx<<" "<<ty<<" ";
//cout<<d[tx][ty]<<endl;
for(int i=0;i<4;i++){
int x = tx+dx[i];
int y = ty+dy[i];
if(x<0||x>=n||y<0||y>=m||g[x][y]!=1||d[x][y]!=-1) continue;
d[x][y]=dis+1;
q.push({dis+1,x,y}); //更新下一层橘子
}
}
int ans = 0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(g[i][j]==1&&d[i][j]==-1) //找到没有被感染的橘子
return -1;
else{
ans=max(ans,d[i][j]);
}
return ans;
}
};