一、问题描述


二、解题思路
由于本题的腐烂操作为就近、同时并且需要求最小分钟数,所以本题本质上是一个多源bfs问题,多源bfs的核心在出队列时对批次进行计数,而不是按单纯节点数进行计数,解题思路如下:
(1)首先,遍历grid,统计橘子的总数,将腐烂的橘子加入队列;
(2)接下来进行多源bfs广度优先搜索:
<1>统计当前队列中元素的数量,即当前分钟能进行辐射腐烂的橘子数量。更新orange的值为当前新鲜的橘子数量。bool变量rotted用于标记当前分钟是否有橘子腐烂;
<2>将当前队列中的所有元素出队,于此同时,将其四周新鲜的橘子加入队列,即进行腐烂操作,如果本轮进行了腐烂操作,就将rotted更新为true。本分钟的腐烂操作完成后,根据rotted的值更新time;
<3>如果orange==0,即新鲜的橘子数量为0,就返回time。否则,表示不可能全部腐烂。返回-1。
三、代码实现
cpp
class Solution {
int N,M;
vector<vector<bool>> visited;
public:
int orangesRotting(vector<vector<int>>& grid) {
//多源BFS->按批次计数
//全局变量初始化
N=grid.size();
M=grid[0].size();
queue<pair<int,int>> q;
int orange=0;
//统计橘子的数量,将腐烂的橘子加入队列
for(int i=0;i!=N;i++)
for(int j=0;j!=M;j++){
if(grid[i][j]==1) orange++;
else if(grid[i][j]==2){
q.push({i,j});
orange++;
}
}
int dx[4]={0,1,0,-1};
int dy[4]={-1,0,1,0};
int time=0;
while(!q.empty()){
//当前分钟腐烂的橘子数
int bad=q.size();
orange-=bad;
//本轮是否腐烂新橘子
bool rotted=false;
while(bad--){
pair<int,int> cur=q.front();q.pop();
int cur_x=cur.first;
int cur_y=cur.second;
for(int i=0;i!=4;i++){
int new_x=cur_x+dx[i];
int new_y=cur_y+dy[i];
if(new_x>=0&&new_x<N&&new_y>=0&&new_y<M&&grid[new_x][new_y]==1){
q.push({new_x,new_y});
grid[new_x][new_y]=2;
rotted=true;
}
}
}
if(rotted) time++;
}
return orange==0?time:-1;
}
};