在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
解题思路:其实就是一个传染问题,腐烂橘子会传染新鲜橘子,直到传染完毕或者无法传染为止
1.BFS
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid) {
int time=-1,fresh=0,lan=0,sum=0;
int hang=grid.size();
int lie=grid[0].size();
queue<pair<int, int>> q;//存烂橘子
for(int i=0;i<hang;++i){
for(int j=0;j<lie;j++){
if(grid[i][j]==1){
fresh++;//新鲜橘子
}
if(grid[i][j]==2){
q.push({i,j});
lan++;//统计烂橘子
}
}
}
if(fresh==0){
return 0;
}
while(!q.empty()){
int n=q.size();//此时q内已经存了n个烂橘子,要先将这n个进行bfs
for(int i=0;i<n;i++){//存进去的n个橘子,不能一个个遍历,因为新传染的在此轮中是不能进行传染的
auto t=q.front();//得到x1,y1
int x1=t.first;
int y1=t.second;
q.pop();//q出队
if(x1-1>=0 && grid[x1-1][y1]==1){//上
grid[x1-1][y1]=2;//原本的新鲜橘子变成烂橘子
q.push({x1-1,y1});//新的烂橘子入队
fresh--;//新鲜橘子减一
}
if(x1+1<hang &&grid[x1+1][y1]==1){//下
grid[x1+1][y1]=2;
q.push({x1+1,y1});
fresh--;
}
if(y1-1>=0 &&grid[x1][y1-1]==1){
grid[x1][y1-1]=2;
q.push({x1,y1-1});
fresh--;
}
if(y1+1<lie &&grid[x1][y1+1]==1){
grid[x1][y1+1]=2;
q.push({x1,y1+1});
fresh--;
}
}
time++;
}
if(fresh!=0){//有新鲜橘子感染不了
time=-1;
}
return time;
}
};
2.超时但是可行版本
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid) {
int time=-1,fresh=0,lan=0,sum=0,newlan=0;
int hang=grid.size();
int lie=grid[0].size();
for(int i=0;i<hang;++i){
for(int j=0;j<lie;++j){
if(grid[i][j]==1){
fresh++;
sum++;
}
if(grid[i][j]==2){
q.push({i,j});
lan++;
sum++;
}
}
}
if(fresh==0){
return 0;
}
while(lan!=sum){
time++;
for(int i=0;i<hang;++i){
for(int j=0;j<lie;++j){
if(grid[i][j]==2){
if(i-1>=0 && grid[i-1][j]==1){
grid[i-1][j]=3;
newlan++;
fresh--;
}
if(i+1<hang &&grid[i+1][j]==1){
grid[i+1][j]=3;
newlan++;
fresh--;
}
if(j-1>=0 &&grid[i][j-1]==1){
grid[i][j-1]=3;
newlan++;
fresh--;
}
if(j+1<lie &&grid[i][j+1]==1){
grid[i][j+1]=3;
newlan++;
fresh--;
}
}
}
}
if(newlan==0){
return -1;
}
for(int i=0;i<hang;++i){
for(int j=0;j<lie;j++){
if(grid[i][j]==3){
grid[i][j]=2;
}
}
}
}
return time;
}
};