【简单】Leetcode-腐烂的橘子//广度优先搜索

在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
在这里插入图片描述
示例一:
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出: 4

示例二:
输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

示例三:
输入:[[0,2]]
输出: 0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。

思路:利用队列。先遍历一遍数组,将腐烂的橘子入队。接着每次让队首橘子周围的新鲜橘子腐烂,然后出队。以此类推,最后再遍历一遍数组,发现有新鲜橘子就返回-1,否则返回时间

int orangesRotting(vector<vector<int>>& grid) {
        queue<pair<int, int>> que;
        for (int i = 0; i < grid.size(); i++)
        {
            for (int j = 0; j < grid[i].size(); j++)
            {
                if (grid[i][j] == 2) que.push(make_pair(i,j));
            }
        }
        int minutes = 0;
        while (!que.empty())
        {
            int size = que.size();
            bool flag = false;
            while (size--)
            {
                int x = que.front().first;
                int y = que.front().second;
                que.pop();
                //行数小于最后一行的都可以腐烂其下方的橘子
                //因为数组从0开始计数,所以最后一行的下标是grid.size() - 1
                if (x < grid.size() - 1 && grid[x + 1][y] == 1)
                {
                    grid[x + 1][y] = 2;
                    que.push(make_pair(x + 1, y));
                    flag = true;
                }
                //行数大于第0行的都可以腐烂上方的橘子
                if (x - 1 >= 0 && grid[x - 1][y] == 1)
                {
                    grid[x - 1][y] = 2;
                    que.push(make_pair(x - 1, y));
                    flag = true;
                }
                //列数大于第0列的都可以感染左方的橘子
                if (y - 1 >= 0 && grid[x][y - 1] == 1)
                {
                    grid[x][y - 1] = 2;
                    que.push(make_pair(x, y - 1));
                    flag = true;
                }
                //列数小于最右端的都可以感染右边的橘子
                if (y + 1 < grid[0].size() && grid[x][y + 1] == 1)
                {
                    grid[x][y + 1] = 2;
                    que.push(make_pair(x, y + 1));
                    flag = true;
                }
            }
            if (flag) ++minutes; //如果flag为true,说明这一轮有感染的,时间加1
        }
        for (int i = 0; i < grid.size(); i++)
        {
            for (int j = 0;j < grid[i].size(); j++)
            {
                if (grid[i][j] == 1) return -1;
            }
        }
        return minutes;
    }

总结:我刚开始让周围橘子腐烂的代码是这样,这样有两个问题

				if (x <= 1 && grid[x + 1][y] != 0)
                {
                    grid[x + 1][y] = 2;
                    que.push(make_pair(x + 1, y));
                    flag = true;
                }
                if (x >= 1 && grid[x - 1][y] != 0)
                {
                    grid[x - 1][y] = 2;
                    que.push(make_pair(x - 1, y));
                    flag = true;
                }
                if (y >= 1 && grid[x][y - 1] != 0)
                {
                    grid[x][y - 1] = 2;
                    que.push(make_pair(x, y - 1));
                    flag = true;
                }
                if (y <= 1 && grid[x][y + 1] != 0)
                {
                    grid[x][y + 1] = 2;
                    que.push(make_pair(x, y + 1));
                    flag = true;
                }
  1. 有一个样例会让程序陷入死循环,比如只有两个并排的腐烂橘子时。所以判断条件应该是grid[x][y] == 1,而不是 grid[x][y] != 0。否则grid[x][y]==2也会被算进去,但其实这个橘子已经是腐烂的了,不能再加入了。
  2. 我刚开始以为永远是3*3的九宫格,其实是任意格子大小,所以&&符号前的判断条件也错了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值