关于这道题我最先想到就是一次一次向四周腐烂,然后输出腐烂时间就行了。实际实现起来的时候发现还得注意这个腐烂橘子到底是早就已经腐烂了的还是刚刚才腐烂的,这就让我想到了用哈希表当条件来进行判断,因为已经腐烂过的橘子周围已经没有新鲜橘子了,所以只要判断刚腐烂的橘子就行了。然后就是关于腐烂完毕的判断,我实际设了一个temp来保存上一次的腐烂橘子数来作比较,如果temp等于橘子总数,则完全腐烂,返回时间;在temp不等于橘子总数的情况下,如果temp等于现在的腐烂橘子数,就说明没有新增腐烂橘子,返回-1。具体思路如下:
1.首先要考虑的是没有新鲜橘子的情况
2.然后就是有新鲜橘子
2.0腐烂的具体循环思路
大概就是新建一个二维数组当哈希表,腐烂橘子每腐烂一次周围的橘子,就把新腐烂的橘子对应的哈希表值+1,以此来判断橘子是不是最新腐烂的,因为已经腐烂的橘子无法再次对周围橘子进行腐烂,所以下一次判断的时候就直接以新腐烂的橘子和哈希表值为条件,对新腐烂橘子的四周进行腐烂。
2.1腐烂完毕的判断
每腐烂一次就记录一下当前的腐烂橘子数,如果当前腐烂橘子数等于橘子总数的话,就返回时间就行了;
如果没有新增腐烂橘子,也就是当前腐烂橘子数等于上一次的腐烂橘子数且腐烂橘子数不等于橘子总数,就说明有橘子无法被腐烂,返回-1
代码如下:
int orangesRotting(int** grid, int gridSize, int* gridColSize){
int dx[4]={-1,0,1,0};//上左下右
int dy[4]={0,-1,0,1};
//申请二维数组空间并初始化
int** res=(int**)malloc(sizeof(int*) * gridSize);
for(int i=0;i<gridSize;i++)
{
*(res+i)=(int*)malloc(sizeof(int) * (*gridColSize));
for(int j=0;j<*gridColSize;j++)
{
res[i][j]=1;//所有橘子对应的第几分钟
}
}
//没有新鲜橘子的情况
int flag=0;
for(int i=0;i<gridSize;i++)
{
for(int j=0;j<*gridColSize;j++)
{
if(grid[i][j]==1)
{
flag=1;
}
}
}
if(flag==0)
{
return 0;
}
//有新鲜橘子的情况
int flag1=0;
int total=0;//橘子总数
int count=0;//腐烂的橘子数目
int minute=1;//第几分钟
while(1)
{
int temp=count;//保存这一次循环之前腐烂的橘子的个数
for(int i=0;i<gridSize;i++)
{
for(int j=0;j<*gridColSize;j++)
{
//统计橘子总数
if(grid[i][j]!=0 && flag1==0)
{
total++;
}
//污染橘子
if(grid[i][j]==2 && res[i][j]==minute)//标记(时间)正确并且该位置为腐烂的橘子
{
for(int m=0;m<4;m++)
{
if(i+dx[m]<gridSize && 0<=i+dx[m] && 0<=j+dy[m] && j+dy[m]<*gridColSize && grid[i+dx[m]][j+dy[m]]==1)//坐标不会越界且周围橘子为新鲜的时
{
grid[i+dx[m]][j+dy[m]]=2;
res[i+dx[m]][j+dy[m]]=minute+1;
}
}
}
}
}
flag1=1;//防止第二次计算橘子总数
minute++;
//统计现在的腐烂橘子数量
count=0;
for(int i=0;i<gridSize;i++)
{
for(int j=0;j<*gridColSize;j++)
{
if(grid[i][j]==2)
{
count++;
}
}
}
//腐烂完毕,输出结果
if(count==total)//腐烂橘子等于橘子总数,腐烂完毕
{
return minute-1;
}
else if(count==temp)//腐烂橘子不等于橘子总数,但是已经没有新增的腐烂橘子,说明有橘子无法腐烂
{
return -1;
}
}
}
力扣刷了这么久,终于能完全靠自己单通中等题了,花了两个多小时写出来的,感觉有很多可以优化的地方,第一次写博客,为了纪念此刻并且防止下次看到这题又跟新的一样,就粗略记录一下,不足之处望指出。