leetcode 热题100(994. 腐烂的橘子)bfs实现c++

链接:994. 腐烂的橘子 - 力扣(LeetCode)

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

  • 值 0 代表空单元格;
  • 值 1 代表新鲜橘子;
  • 值 2 代表腐烂的橘子。

每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

示例 1:

输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4

示例 2:

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

示例 3:

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

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] 仅为 01 或 2

题意

求出让所有橘子都腐败的时间

思路

因为每个腐败橘子都会传染周围的橘子,同时每个腐败橘子都是一起传染周围,所以我们直接就想到用优先队列了。起始我们把腐败橘子都记录下来,并且标记一下距离d[i][j]=0,然后加入队列,接着就可以直接遍历队列套模板了。

代码如下

class Solution {
public:
    int dx[4]={-1,0,1,0}; //四个方向
    int dy[4]={0,-1,0,1}; //四个方向
    struct node{
        int dis; //距离
        int x,y; //坐标
        bool operator <(const node &W)const{  //自定义排序
            return dis>W.dis;
        }
    };

    int orangesRotting(vector<vector<int>>& g) {
        int n=g.size(),m=g[0].size();
        vector<vector<int>> d(n,vector<int>(m,-1));

        priority_queue<node> q; //定义小根堆,因为前面node结构体已经自定义排序了

        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(g[i][j]==2)
                {
                    q.push({0,i,j});
                    d[i][j]=0;
                }

        while(q.size()){
            auto t = q.top();
            q.pop();
            int dis = t.dis;
            int tx = t.x,ty=t.y;
            //cout<<tx<<" "<<ty<<" ";
                    //cout<<d[tx][ty]<<endl;
            for(int i=0;i<4;i++){
                int x = tx+dx[i];
                int y = ty+dy[i];
                if(x<0||x>=n||y<0||y>=m||g[x][y]!=1||d[x][y]!=-1) continue;
                d[x][y]=dis+1;
                q.push({dis+1,x,y}); //更新下一层橘子
            }
        }
        int ans = 0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(g[i][j]==1&&d[i][j]==-1) //找到没有被感染的橘子
                    return -1;
                else{
                    ans=max(ans,d[i][j]);
                    
                }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值