题目
在给定的 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
正解
多源广度优先搜索
链接
自解
class Solution {
public:
struct point {
int i,j;
point(int i, int j) : i(i),j(j) {}
};
int orangesRotting(vector<vector<int>>& grid) {
int level = -1;
int restfresh = 0;
//int lastrestfresh = 0;
queue<point> buf;
for(int i=0;i<grid.size();i++) {
for(int j=0;j<grid[0].size();j++) {
if (grid[i][j] == 2) {
buf.push(point(i, j));
//grid[i][j] = 1; //坏的先变成好的避免lastrestfresh == restfresh第一次就出现
//restfresh++; //坏的先变成好的避免lastrestfresh == restfresh第一次就出现
}
else if(grid[i][j]==1) {
restfresh++;
}
}
}
if(restfresh == 0) //[[0]]
return 0;
while(!buf.empty()) {
int levelsize = buf.size();
level++;
// if(restfresh == 0)
// return level;
// else if(lastrestfresh == restfresh)
// return -1;
// else {
// lastrestfresh = restfresh;
// }
for(int m=0;m<levelsize;m++) {
point tmp = buf.front();
buf.pop();
// if(grid[tmp.i][tmp.j]==1) { //放在这里level会+1
// grid[tmp.i][tmp.j]=2;
// restfresh--;
// }
if (tmp.i - 1>=0 && grid[tmp.i - 1][tmp.j]==1) {
buf.push(point(tmp.i - 1,tmp.j));
grid[tmp.i - 1][tmp.j]=2;
restfresh--;
}
if (tmp.i + 1<grid.size() && grid[tmp.i + 1][tmp.j]==1) {
buf.push(point(tmp.i + 1,tmp.j));
grid[tmp.i + 1][tmp.j]=2;
restfresh--;
}
if (tmp.j - 1>=0 && grid[tmp.i][tmp.j - 1]==1) {
buf.push(point(tmp.i,tmp.j - 1));
grid[tmp.i][tmp.j - 1]=2;
restfresh--;
}
if (tmp.j + 1<grid[0].size() && grid[tmp.i][tmp.j + 1]==1) {
buf.push(point(tmp.i,tmp.j + 1));
grid[tmp.i][tmp.j + 1]=2;
restfresh--;
}
}
}
if(restfresh == 0)
return level;
else
return -1;
}
};