这道题属于是BFS的模板题,很像病毒扩散的过程,之前在刷代码随想录的时候也刷过类似的题目,具体的BFS代码写法可以参照这篇博客我们需要统计出腐烂至全地图时所需的最少扩散次数,当然也存在有的橘子无法被腐烂的情况,因此我们需要先统计初始状态下的新鲜橘子个数,每当扩散一次,被扩散的新鲜橘子就变成腐烂橘子,并将新鲜的橘子数减去对应的数量,当扩散结束后,如果新鲜的橘子数量大于0,则说明无法腐烂所有的橘子,我们直接返回-1
,否则就直接返回扩散的轮数。由于初始状态下的腐烂橘子可能不止一个,我们需要将初始状态下的腐烂橘子坐标添加到队列中,然后再开始扩散。扩散过程需要用两重while
循环来实现,外层while
循环每循环一次,就代表扩散了一次,内层while
循环每循环一次,就是从当前的其中一个腐烂橘子向四周扩散了一次,被腐烂的橘子将加入队列,但是不会参与内层循环的过程,因为在内层循环腐烂的橘子并不是本轮的初始腐烂橘子,应当在下一次外层while
循环中进行扩散。
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid) {
int result = 0;
//定义4个方向
vector<vector<int>> dirs ={
{0, 1}, //向右
{0, -1}, //向左
{1, 0}, //向下
{-1, 0} //向上
};
int m = grid.size(), n = grid[0].size(); //m行n列
int fresh = 0; //统计初始状态下新鲜橘子的数量
queue<pair<int, int>> My_Queue; //用于存放网格坐标
//统计新鲜的橘子数量和腐烂橘子的初始位置
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == 1)
fresh++;
if(grid[i][j] == 2)
My_Queue.push({i, j});
}
}
while(fresh > 0 && !My_Queue.empty()){
int size = My_Queue.size();
while(size > 0){
pair<int, int> current = My_Queue.front();
My_Queue.pop();
size--;
for(auto dir : dirs){
int next_x = current.first + dir[0];
int next_y = current.second + dir[1];
if((next_x < 0 || next_x >= m) || (next_y < 0 || next_y >= n))
continue; //越界访问直接跳过
if(grid[next_x][next_y] == 1){
grid[next_x][next_y] = 2;
fresh--;
My_Queue.push({next_x, next_y});
}
}
}
result++;
}
return fresh > 0 ? -1 : result;
}
};