原题链接994. 腐烂的橘子 - 力扣(LeetCode)
思路:采用bfs遍历图,将烂橘子加入队列,然后将被烂橘子感染的橘子也加入队列,bfs的具体细节就不多说了,可以自己去搜,很简单,这里主要写本题需要注意的问题。
第一个时间问题,很多橘子同时感染,如果按照传统的bfs方法去写
是假设是每分钟只有一个橘子变坏,但同时间有很多坏橘子,这些坏的橘子同时影响别的橘子
所以需要改进,这里采用bfs的一个特性,最短路径的记录,过程看图
这样就可以记录那个橘子是什么时候烂的。、
class Solution {
private:int ans = 0;
int cnt = 0;//新鲜橘子数量
int time[10][10];//记录橘子是第几分钟腐烂的
queue<pair<int, int>>q;//同时间有很多坏橘子,这些坏的橘子同时影响别的橘子,所以要记录第一次遍历时遇到的所有坏橘子
public: void bfs(vector<vector<int>>& grid)
{
int dx[4][2] = { -1,0,0,1,1,0,0,-1 };
while (!q.empty())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++)
{
int nex = dx[i][0] + t.first;
int ney = dx[i][1] + t.second;
if (nex < 0 || nex >= grid.size() || ney < 0 || ney >= grid[0].size()||time[nex][ney]!=-1||grid[nex][ney]==0)continue;
time[nex][ney] = time[t.first][t.second] + 1;//bfs特性
q.push({ nex,ney });
cnt--;
ans = time[nex][ney];
if (cnt==0) {
break;
}
}
}
}
int orangesRotting(vector<vector<int>>& grid) {
int n = grid.size(), m = grid[0].size();//n是多少行,m是多少列
memset(time, -1, sizeof(time));//bfs通用操作,先将用不到的点标记为-1
for(int i=0;i<n;i++)//检测那个橘子烂了
for (int j = 0; j < m; j++)
{
if (grid[i][j] == 2)
{
q.push({ i,j });
time[i][j] = 0;//初始烂橘子的时间设为0
}
else {
if (grid[i][j] == 1)
{
cnt++;
}
}
}
bfs(grid);
return cnt == 0 ? ans : -1;
}
};