(力扣)LeetCode994. 腐烂的橘子(C语言)

一、环境说明

  1. 本文是 LeetCode 994题 : 腐烂的橘子,使用c语言实现
  2. 模拟广度优先遍历。
  3. 测试环境:Visual Studio 2019

二、代码展示

typedef struct queue{//创建队列,用于存储坐标
    int x;
    int y;
}queue;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
int orangesRotting(int** grid, int gridSize, int* gridColSize) {
    int m = gridSize;//行数
    int n = gridColSize[0];//列数
    int** dis = (int**)calloc(m, sizeof(int*));//存放最小分钟数
    for (int i = 0; i < m; i++) {
        dis[i] = (int*)calloc(n, sizeof(int));//每一行对应n列
        memset(&dis[i][0], -1, n * sizeof(int));//初始化dis内全部为-1
    }
    queue* q = (queue*)calloc(m * n, sizeof(queue));//最多可能全部入队
    int front = 0, rear = 0, cnt = 0;//队首队尾指针,维护队列。cnt用于计数新鲜的橘子。
    for (int i = 0; i < m; i++) {//从上到下,从左到右,遍历所有橘子
        for (int j = 0; j < n; j++) {
            if (2 == grid[i][j]) {//腐烂的橘子,坐标入队
                q[rear].x = i;
                q[rear++].y = j;
                dis[i][j] = 0;
            }
            else if (1 == grid[i][j]) {//遇到新鲜的橘子,计数
                cnt++;
            }
        }
    }
    int ans = 0;//返回的答案值
    while (front != rear) {//队列内存在元素
        int x = q[front].x, y = q[front++].y;//队首元素出队,并保存坐标
        for (int i = 0; i < 4; i++) {
            int new_x = x + dx[i], new_y = y + dy[i];
            if (new_x >= 0 && new_x < m && new_y >= 0 && new_y < n &&-1==dis[new_x][new_y]&&grid[new_x][new_y]) {//边界保护&&dis==-1**&&grid不为0
                dis[new_x][new_y] = dis[x][y] + 1;
                q[rear].x = new_x;//被腐烂的点入队
                q[rear++].y = new_y;
                if (1 == grid[new_x][new_y]) {//遍历到新鲜橘子
                    cnt--;
                    ans = dis[new_x][new_y];
                    if (0 == cnt) {//没有新鲜橘子了
                        break;
                    }
                }
            }
        }
    }
    return cnt?-1:ans;
}

三、思路分析

  • 模拟广度优先遍历的方法,将初始情况下所有腐烂的橘子看做一个超级源点来感染他们,初始时间为-1,则超级源点腐烂所有橘子的时刻为0。则-1时刻所有橘子都被视为新鲜的橘子。
  • 用一个队列存储所有已腐烂的橘子,-1时刻存储0时刻要腐烂的橘子,0时刻存储1时刻被腐烂的橘子,依次往后递推。
  • 边界设置:首先要保证在二维数组范围内,其次每次访问的元素必须未被访问过,也就是dis==-1则访问。最后单元格不能为空,grid!=0。上述条件,保证被访问的单元格,只能是新鲜的橘子。
  • 由于广度优先遍历的特性,他是一圈一圈访问的,可以保证,一次遍历的结果,对应的dis就是每个点对应的腐烂时间,-1表示未被腐烂,或者空点。而ans最终一定等于最后一个被腐烂的橘子,花费的时间。

四、代码分析

  • 见注释~

五、AC

AC

六、复杂度分析

  1. 时间复杂度:O(mn) ,m是行数,n是列数,O(mn)是遍历所有元素的时间开销。
  2. 空间复杂度:O(mn),使用了额外的队列,大小为O(mn),使用了额外的dis二维数组,表示腐烂的时间,大小也为O(mn)。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值