原题链接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通用操作,先将用不到的点标记为-1for(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;}
};