BFS 解决最短路径问题, 迷宫中离入口最近的出口,最小基因变化,单词接龙,为高尔夫比赛砍树

news2024/10/1 2:32:48

文章目录

  • 1926. 迷宫中离入口最近的出口
  • 433. 最小基因变化
  • 127. 单词接龙
  • 675. 为高尔夫比赛砍树

1926. 迷宫中离入口最近的出口

在这里插入图片描述

边权为1的最短路径问题

  1. 我们要知道上下左右都是可以走的 (用队列)
  2. 走过的地方不要在走了,这样会进入死循环(可以把走过的地方变成墙 “.” -> “+”) (创建vis[101][101]对走过的路标记)
  3. 获取到上下左右坐标的时候确认是路 “.” 还是墙 “+” (判断条件)
  4. 判断是否在边界,如果达到边界位置就可以返回对应步数 (判断条件)
  5. 如果发现四周都是墙的时候,说明出不去了,返回 -1
  6. 先走完所有子级的上下左右后,在走 (进出队列)

在这里插入图片描述

class Solution {
public:
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0}; //上下左右走使用
    bool vis[101][101]; //对走过的路标记

    int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {
        int m = maze.size();
        int n = maze[0].size();
        memset(vis,0,sizeof(vis));

        int ret = 0;
        queue<pair<int,int>> q; //创建队列
        q.push({entrance[0],entrance[1]}); //将目前自己所处位置放入队列
        vis[entrance[0]][entrance[1]] = true;//对走过的路标记
        while(q.size())//没有走出去就一直走
        {
            ret++; //步数++
            int sz = q.size();
            for(int i = 0; i<sz; i++) //通过队列里面有几个来选择循环次数
            {
                auto [a,b] = q.front();//取头
                q.pop();//取完就可以退出队列
                for(int j = 0; j<4; j++) //对四个方向判断,如果是边界就出去,不是就进入队列
                {
                    int x = a + dx[j];
                    int y = b + dy[j];
                    if(x >= 0 && x < m && y >= 0 && y < n && maze[x][y] == '.' && !vis[x][y])//判断条件,不能走墙壁和标记过的路
                    {
                        if(x == 0 || x == m-1 || y == 0 || y == n-1)//边界条件
                            return ret; 
                        q.push({x,y});//不是边界且可以走就进入队列
                        vis[x][y] = true;//标记
                    }
                }
            }
        }
        return -1; //无法走出去就返回-1
    }
};

433. 最小基因变化

在这里插入图片描述
思路分析:
由题可知:基因序列 A 变化至另一个基因序列 B,需要满足一下条件:

  1. 序列 A 与 序列 B 之间只有一个字符不同;
  2. 变化字符只能从 ‘A’, ‘C’, ‘G’, ‘T’ 中进行选择;
  3. 变换后的序列 B 一定要在字符串数组 bank 中。

具体的大概思路就是利用回溯的方式是逐个改变基因中的字符(A、C、G、T),当改变后的基因在基因库中 步数 num+1 并进入下一层。
但是本题是有限制条件就是每一次基因变化都要能在基因库中找到,因此单层处理逻辑中需要遍历基因库,找到库中与当前基因相差一个字符的就是下一步变化的基因,这时步数 num+1 并进入下一层。

在这里插入图片描述

class Solution {
public:
    int minMutation(string startGene, string endGene, vector<string>& bank) {
        unordered_set<string> vis; //已经搜索过的基因库
        unordered_set<string> hash(bank.begin(),bank.end()); 存储基因库里面的字符串
        string change = "ACGT";

        if(!hash.count(endGene)) return -1; //最终基因在基因库中找不到返回-1
        if(startGene == endGene) return 0; //如果相等就直接返回0

        queue<string> q;//创建队列
        q.push(startGene);//放入最初的基因
        vis.insert(startGene);//放入已经搜索过的基因库

        int ret = 0;
        while(q.size())
        {
            ret++;//次数++
            int sz = q.size();
            while(sz--) //队列里的个数决定循环次数
            {
                string s = q.front();//取头
                q.pop();
                for(int i = 0; i<8; i++) //循环8次是因为基因长度为8,每一个都有四种变化
                {
                    string tmp = s; //不能直接对原基因修改,用tmp代替
                    for(int j = 0; j<4; j++) //四种替换情况
                    {
                        tmp[i] = change[j]; //替换单个字符
                        if(hash.count(tmp) && !vis.count(tmp)) //变化后的基因必须位于基因库中并且没有标记过
                        {
                            if(tmp == endGene) //变化完成就返回
                                return ret;
                            q.push(tmp); //没有完成就接着进入队列
                            vis.insert(tmp);//进行标记
                        }
                    }
                }

            }
        }
        return -1; //都不能变化成就返回-1
    }
};

127. 单词接龙

在这里插入图片描述

跟上面那道题思路完全一样,留给各位练习使用

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
            unordered_set<string> hash(wordList.begin(),wordList.end());
            unordered_set<string> vis;

            if(!hash.count(endWord))   return 0;

            queue<string> q;
            q.push(beginWord);
            vis.insert(beginWord);

            int ret = 1;
            while(q.size())
            {
                ret++;
                int sz = q.size();
                while(sz--)
                {
                    string t = q.front();
                    q.pop();
                    for(int i = 0; i<t.size(); i++)
                    {
                        string tmp = t;
                        for(char ch = 'a'; ch <= 'z'; ch++)
                        {
                            tmp[i] = ch;
                            if(hash.count(tmp) && !vis.count(tmp))
                            {
                                if(tmp == endWord) return ret;
                                q.push(tmp);
                                vis.insert(tmp);
                            }
                        }
                    }
                }
            }
            return 0;
       }
};

675. 为高尔夫比赛砍树

在这里插入图片描述
由题意可以知道:

  1. 先找出砍树的顺序
  2. 按顺序进行砍树
  3. 按顺序进行砍树就是bfs算法
class Solution {
    int m, n;
public:
    int cutOffTree(vector<vector<int>>& forest) {
        //1.找出砍树的顺序
        vector<pair<int,int>> trees; //创建vector数组放入有树的坐标
        for(int i = 0; i<forest.size(); i++)
        {
            for(int j = 0; j<forest[0].size(); j++)
            {
                if(forest[i][j] > 1)
                    trees.push_back({i,j});
            }
        }
		
		//将这些坐标按照树的高低进行排序,由题目要求:由低到高
        sort(trees.begin(),trees.end(),[&](const pair<int,int>& p1, const pair<int,int>& p2)
        {
            return forest[p1.first][p1.second] < forest[p2.first][p2.second];
        });

        //2.按顺序砍树
        int ax = 0,ay = 0;
        int ret = 0;
        for(auto& [a,b] : trees)
        {
            int step = bfs(forest,ax,ay,a,b); //bfs从(ax,ay)到(a,b)的最短步数
            if(step == -1)
                return -1;
            ret += step; //然后依次相加
            ax = a, ay = b; //将(a,b)赋给(ax,ay),然后再次循环进入bfs
        }

        return ret;
    }

    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    bool vis[51][51];
    int bfs(vector<vector<int>>& forest,int bx,int by, int ex, int ey)//bfs和之前都一样
    {
        if(bx == ex && by == ey) return 0;
        queue<pair<int,int>> q;
        memset(vis,0,sizeof(vis));
        q.push({bx,by});
        vis[bx][by] = true;

        int step = 0;
        while(q.size())
        {
            step++;
            int sz = q.size();
            while(sz--)
            {
                auto [a,b] = q.front();
                q.pop();
                for(int i = 0; i<4; i++)
                {
                    int x = a + dx[i];
                    int y = b + dy[i];
                    if(x >= 0 && x < forest.size() && y>=0 && y < forest[0].size() && forest[x][y] && !vis[x][y])
                    {
                        if(x == ex && y == ey) return step;
                        q.push({x,y});
                        vis[x][y] = true;
                    }
                }
            }
        }
        return -1;
    }

};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零信任内网安全访问

随着互联网的持续发展&#xff0c;便捷的共享方式极大地提高了企业的生产力和工作效率&#xff0c;但随之也给企业内网带来了极大的安全隐患。企业内网承载大量的核心资产和机密数据&#xff0c;一旦受到攻击可能会造成大量损失&#xff0c;因此&#xff0c;如何通过零信任内网…

快手一面:给定一棵二叉树,要求将其转换为其镜像?

目录标题 题解&#xff1a;二叉树的镜像&#xff08;Invert Binary Tree&#xff09;问题描述示例解题思路代码实现详细分析复杂度分析优点注意事项&#x1f495; 题解&#xff1a;二叉树的镜像&#xff08;Invert Binary Tree&#xff09; 问题描述 给定一棵二叉树&#xff…

探索AI新纪元:揭秘Mammoth库的神秘面纱

文章目录 探索AI新纪元&#xff1a;揭秘Mammoth库的神秘面纱背景&#xff1a;为何选择Mammoth&#xff1f;简介&#xff1a;Mammoth是什么&#xff1f;安装&#xff1a;如何获取Mammoth&#xff1f;使用&#xff1a;Mammoth的基本函数场景应用&#xff1a;Mammoth在实际中的运用…

基于Python大数据的B站热门视频的数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

宠物空气净化器和普通的空气净化器有区别吗?哪款能吸猫毛

这不是国庆节要来了吗&#xff0c;想着假期变多了可以多陪一下自家的小猫咪&#xff0c;但是也怕猫咪的毛发太多让我产生退缩的念头。 刚开始养的时候&#xff0c;我就知道猫咪是会掉毛的&#xff0c;毕竟猫咪的毛发这么旺盛&#xff0c;掉毛也是正常的&#xff0c;但是我似乎…

SpringCloud源码:客户端分析(二)- 客户端源码分析

背景 我们继续分析EurekaClient的两个自动化配置类&#xff1a; 自动化配置类功能职责EurekaClientAutoConfiguration配置EurekaClient确保了Eureka客户端能够正确地&#xff1a;- 注册到Eureka服务端- 周期性地发送心跳信息来更新服务租约- 下线时通知Eureka服务端- 获取服务实…

Qt网络编程——QUdpSocket

文章目录 Qt网络编程QUdpSocketUdp回显服务器Udp客户端 Qt网络编程 网络编程本质上是写应用层代码&#xff0c;需要传输层提供支持。 而传输层最核心的协议就是UDP和TCP&#xff0c;这两个协议有较大差别&#xff0c;所以Qt提供了两套API。 要是有Qt网络编程的API&#xff0…

9.23-9.25学习

前置知识 docker&#xff1a;Docker-CSDN博客 docker安装mysql和 redis&#xff1a;https://blog.csdn.net/weixin_73118927/article/details/142530243?fromshareblogdetail&sharetypeblogdetail&sharerId142530243&sharereferPC&sharesourceweixin_7311892…

从预测性维护到智能物流:ARM边缘计算控制器的工业实践

工业4.0时代的到来&#xff0c;边缘计算技术成为连接物理世界与数字世界的桥梁。ARM架构的边缘计算控制器凭借其低功耗、高能效和灵活性等特点&#xff0c;在工业自动化领域展现出巨大潜力。本文将通过几个实际应用案例来探讨ARM边缘计算控制器是如何提升生产线效率和安全性的&…

03DSP学习-利用syscfg配置IO

上一篇博客介绍了syscfg&#xff0c;对syscfg有了初步的了解&#xff0c;但是在真正使用上它之前&#xff0c;还不能理解他是一个神器。 (在写博客的时候&#xff0c;我是在从头到尾重新完成这个步骤&#xff0c;希望对初学者有点帮助) 找到Board Component 打开syscfg文件&…

【Tourism】Yuncheng(4)

文章目录 1、永乐宫&#xff08;AAAA&#xff09;2、寿圣寺3、城隍庙4、池神庙 1、永乐宫&#xff08;AAAA&#xff09; 永乐宫&#xff0c;原名大纯阳万寿宫&#xff0c;位于山西省运城市芮城县以北约三公里处的龙泉村东&#xff0c;是为纪念八仙之一吕洞宾而修建的一座道教宫…

VR虚拟展厅可以在手机上打开吗?

虚拟展厅是可以在手机上打开的。 随着数字技术和虚拟现实技术的不断发展&#xff0c;虚拟展厅已经实现了多平台无缝对接&#xff0c;包括手机、平板、电脑等多种电子设备。具体来说&#xff0c;虚拟展厅通常采用HTML5360全景架构&#xff0c;这种架构使得虚拟展厅不需要安装任…

Mac优化清理工具CleanMyMac X 4.15.6 for mac中文版

CleanMyMac X 4.15.6 for mac中文版下载是一款功能更加强大的系统优化清理工具&#xff0c;软件只需两个简单步骤就可以把系统里那些乱七八糟的无用文件统统清理掉&#xff0c;节省宝贵的磁盘空间。CleanMyMac X 4.15.6 for mac 软件与最新macOS系统更加兼容&#xff0c;流畅地…

2024年配置YOLOX运行环境+windows+pycharm24.0.1+GPU

1.配置时间2024/9/25 2.Anaconda-python版本3.7&#xff0c;yolox版本0.2.0 YOLOX网址: https://github.com/Megvii-BaseDetection/YOLOX 本人下载的这个版本 1.创建虚拟环境 conda create -n yolox37 python37 激活 conda activate yolox37 2.安装Pytorch cuda等&…

vue路由的基本使用

文章目录 1.路由的基本使用2.路由的默认路径3.嵌套路由4.路由懒加载5.动态路由匹配 1.路由的基本使用 安装 vue-router&#xff1a; npm install vue-router创建路由文件&#xff1a; 在 src 目录下创建 router 目录&#xff0c;并在其中创建 index.js 文件。 在 main.js 中使…

【Linux操作系统】进程优先级

目录 一、为什么要有优先级二、进程优先级1.进程优先级的基本概念2.进程优先级的表现形式3. 默认优先级4.进程优先级的修改5.为什么调整优先级是要受限制的&#xff1f; 一、为什么要有优先级 在学习进程优先级之前&#xff0c;我们要先知道为什么会出现进程优先级这个东西 从…

2015年国赛高教杯数学建模A题太阳影子定位解题全过程文档及程序

2015年国赛高教杯数学建模 A题 太阳影子定位 技术就是通过分析视频中物体的太阳影子变化&#xff0c;确定视频拍摄的地点和日期的一种方法。   1.建立影子长度变化的数学模型&#xff0c;分析影子长度关于各个参数的变化规律&#xff0c;并应用你们建立的模型画出2015年10月…

C++入门day3-面向对象编程(下)

前言&#xff1a;C入门day3-面向对象编程&#xff08;中&#xff09;-CSDN博客 初识&#xff1a;继承特性 继承的基础语法 class A{ public:int a; }; class B:public A { public:int b; }; B类通过继承A类后&#xff0c;内部会继承一个int变量 a&#xff1a;从下图我们可以…

Nginx基础详解2(首页解析过程、进程模型、处理Web请求机制、nginx.conf语法结构)

续&#xff1a;Nginx基础详解1&#xff08;单体部署与集群部署、负载均衡、正反代理、nginx安装&#xff09;-CSDN博客 目录 4.Nginx默认首页的过程解析 5.Nginx进程模型的详解 5.1启动nginx后的关于nginx的进程查看 5.2master进程与process进程 5.3Nginx进程图解 5.4wo…

【已解决】【Hadoop】【./bin的使用】bash: ./bin/hdfs: 没有那个文件或目录

在 Hadoop 环境中&#xff0c;决定何时在命令前添加 ./bin 和如何处理路径 /home/hadoop 与 /usr/local/hadoop 的问题&#xff0c;主要取决于你的当前工作目录和环境变量的设置。以下是一些指导原则&#xff1a; 何时使用 ./bin&#xff1a; 当前目录是 Hadoop 安装目录&…