目录
题目:
示例:
分析:
题目给我们一个数组,表示空格,橘子,和腐烂的橘子。
腐烂的橘子每次都会将四周(上下左右)的新鲜橘子变成腐烂的橘子。问我们需要多少次,才能将所有的橘子变成腐烂的橘子。
那么我们只需要每次遍历整个网格,再将腐烂的橘子周围的新鲜橘子变成腐烂橘子就可以了,直接模拟就可以了。
不过有几个需要注意的小细节,不能直接把腐烂橘子周围的新鲜橘子变成腐烂橘子,因为如果直接传染了,那么往后遍历就会遍历到本轮腐烂的橘子,就会再将这个腐烂橘子的周围再变腐烂,这样就无法区分是本来就是腐烂橘子还是本轮被传染的腐烂橘子,导致答案要么是0,要么是-1,要么是1。0就是一开始就没有新鲜橘子,-1就是有些橘子永远不会被传染腐烂,而其他结果都会是1。
因此我们需要将本轮传染的橘子先置为一个数来区分腐烂橘子和新鲜橘子。
在一轮传染完毕之后,再将待腐烂橘子转变为腐烂橘子。
还有一点就是如何分辨网格中有永远无法被传染的橘子。我们只需要在每次传染的时候记录下新鲜橘子的数量,如果本次传染前和上次传染时的新鲜橘子数量一致,那么就说明上次传染根本就没有使任何一个新鲜橘子腐烂,所以是永远都没有办法让所有橘子变腐烂,这时候返回-1即可。
或者是发现网格里已经没有新鲜橘子了,我们就把传染轮数返回出去就可以了。
代码:
class Solution {
public:
int check(const vector<vector<int>>& grid) { //检测有多少个新鲜橘子
int ans=0;
for(vector<int>gr:grid){
for(int g:gr){
if(g==1) ans++;
}
}
return ans;
}
void change(vector<vector<int>>& grid){
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==2){ //将腐烂橘子周围的新鲜橘子设置为待腐烂状态
if(i>=1 && grid[i-1][j]==1) grid[i-1][j]=3;
if(i+1<grid.size() && grid[i+1][j]==1) grid[i+1][j]=3;
if(j>=1 && grid[i][j-1]==1) grid[i][j-1]=3;
if(j+1<grid[0].size() && grid[i][j+1]==1) grid[i][j+1]=3;
}
}
}
}
void biu(vector<vector<int>>& grid){ //将待腐烂的橘子变成腐烂
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==3) grid[i][j]=2;
}
}
}
int orangesRotting(vector<vector<int>>& grid) {
int res=0;
int temp=check(grid); //获取新鲜橘子数量
int t=temp;
while(temp!=0){
res++;
change(grid);
biu(grid);
t=check(grid);
if(t==temp) return -1; //如果本轮的新鲜橘子数量等于上一轮的橘子数量,那么表示总会有橘子永远腐烂不了
temp=t;
}
return res;
}
};
本文含有隐藏内容,请 开通VIP 后查看