十四天算法快速入门第九天之「广度优先搜索 / 深度优先搜索」

写在前面:本文题单均来自力扣的算法刷题计划,开这个系列主要是以题目与题解的形式对一些常见、常用算法进行归类和总结,希望在促进自己学习的同时也能帮助到看到这篇文章的大家。另外,本文并非一天一更~

目录

题目一:542. 01 矩阵 

题目描述:

题目分析:

题解代码:

题目二:994. 腐烂的橘子

题目描述:

题目分析:

题解代码:


题目一:542. 01 矩阵 

题目描述:

题目分析:

这题运用BFS可以求解,我们可以先创建一个ret数组记录mat数组里每个数到0的最短距离,将mat数组里为0的数都在其内记录为0为1的数暂且将其到0的距离记录为一个较大的数(不小于m*n),接着创建一个队列que对mat中的每一个0依次入队,再逐一将其上下左右拓展,若遇到1时,也就是当前位置在ret内记录的距离大于上一步的位置在ret内记录的距离时,取上一步的位置在ret内记录的距离再+1,保证为最短距离,每一个位置拓展完后再出队即可。

题解代码:

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) 
    {
        int r=mat.size();  //mat数组的长、宽
        int c=mat[0].size();
        vector<pair<int,int>> step={{0,-1},{0,1},{-1,0},{1,0}};
        vector<vector<int>> ret(r,vector<int>(c,INT_MAX));  //初始化ret数组
        queue<pair<int,int>> que;
        for(int i=0;i<r;i++)
        {
            for(int j=0;j<c;j++)
            {
                if(mat[i][j]==0)
                {
                    ret[i][j]=0;  //记录0到0的最短距离就是0
                    que.push({i,j});  //将所有0入队
                }
            }
        }
        while(!que.empty())
        {
            auto temp=que.front();  //auto自动识别数据类型
            que.pop();
            for(int i=0;i<4;i++)  //进行拓展
            {
                int x=temp.first+step[i].first;
                int y=temp.second+step[i].second;
                if(x<r && y<c && x>=0 && y>=0)  //防止越界
                {
                    if(ret[x][y]>ret[temp.first][temp.second]+1)  //遇到1了
                    {
                        ret[x][y]=ret[temp.first][temp.second]+1;
                        que.push({x,y});  //出队
                    }
                }
            }
        }
        return ret;
    }
};

题目二:994. 腐烂的橘子

题目描述:

 

题目分析:

经典BFS问题,先将所有腐烂的橘子入队,再同时向上下左右扩散,遇到新鲜的橘子使其腐烂,以此类推,最后再判断有无新鲜的橘子即可。  

题解代码:

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid)
    {
        int r = grid.size();
        int c = grid[0].size();
        vector<pair<int, int>> step = { {-1,0},{1,0},{0,1},{0,-1} };
        queue<pair<int, int>> que;
        for (int i = 0; i < r; i++)  //初始化队列
        {
            for (int j = 0; j < c; j++)
            {
                if (grid[i][j] == 2)
                {
                    que.push({ i,j });
                }
            }
        }
        int time = 0;
        while (!que.empty())
        {
            int size=que.size();
            while(size--)  //当前一波腐烂的橘子同时进行扩散
            {
                auto temp = que.front();
                que.pop();
                for (int i = 0; i < 4; i++)  //开始扩散
                {
                    int x = temp.first + step[i].first;
                    int y = temp.second + step[i].second;
                    if (x >= 0 && x < r && y >= 0 && y < c)
                    {
                        if (grid[x][y] == 1)
                        {
                            grid[x][y] = 2;
                            que.push({ x,y });
                        }
                    }
                }
            }
            if (!que.empty())  //扩散一轮后计时
                time++;
        }
        for (int i = 0; i < r; i++)  //最后再判断还有无新鲜橘子
        {
            for (int j = 0; j < c; j++)
            {
                if (grid[i][j] == 1)
                    return -1;
            }
        }
        return time;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kano_s

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

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

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

打赏作者

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

抵扣说明:

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

余额充值