BFS 解决边权为1的最短路问题

边权为1的最短路问题

最短路问题:

比如说从D->K,找出最短的那条,其中每条路都是有权值,此篇主要讲解的边权为1的最短路问题

即边权都是一样的。

image-20240917202123546

解法就是从起点开始,做一次BFS:

  • 需要一个队列、一个哈希表(检测是否访问过)
  • 起点进入队列,然后哈希表标记
  • 弹出队头元素,将队头元素能去的位置,加入队列
  • 然后将该层依次元素弹出,弹出时继续加入能去的位置(哈希表检测一下)
  • 到终点就停止

BFS为什么能找出最短路径:

简单理解一下,假设有4条路,相当于4个人一起出发,每个人每次都向后移动一个单位(因为权值为1),最先到的那一个,就直接“跳出循环”了。

image-20240917203151230

如何找出最短路径:

拓展的层数,就是最短路的长度

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

题目链接:1926. 迷宫中离入口最近的出口

题目解析

题目给了我们两个数组:

  • 二维数组表示迷宫,+表示墙(不能走),.表示空格(可以走)
  • 一维数组:当前起始位置

每次只能往上下左右走一步,遇见墙不能走,让我们求最少走多少步,能走到迷宫(走到就行,不用走出去,没有出口就返回-1)。

矩阵大小为m*n

出口是矩阵的边界位置:x == 0 || x == m -1 || y == 0 || y == n -1

算法原理

每次走一步,找到最少步数,即可以理解为边权为1的最短路问题

  • 每次只能往上下左右走一步
  • 遇墙不走,第一次到边界就直接返回

代码实现

class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};bool vis[101][101];int m = 0;int n = 0;int nearestExit(vector<vector<char>>& maze, vector<int>& entrance){int ret = 0;m = maze.size();n = maze[0].size();//memset(vis, 0, sizeof(vis));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 [x, y] = q.front();q.pop();for(int k = 0; k < 4; k++){int a = dx[k] + x;int b = dy[k] + y;if(a >= 0 && a < m && b >= 0 && b < n && maze[a][b] == '.' && !vis[a][b]){if(a == 0 || a == m -1 || b == 0 || b == n -1){return ret;}q.push({a, b});vis[a][b] = true;}}}}return -1;}
};

433. 最小基因变化

题目链接:433. 最小基因变化

题目解析

给我们2个基于序列(字符串)startend,再给我们一个基因库序列(vector<string>bank,它们都是由8个字符组成,每个字符都是ACGT其中之一

要我们找出从start 变为 end的最短次数,且每次变化,必须要在基因库能找到对应的。

算法原理

每次只能改变基于序列的一个字符,相当于中间可能会产生很多基因序列,然后才到目标序列。

将起始基于序列抽象成一个点,中间的序列抽象成路径,目标序列也是一个点,这样即转换成了求边权为1的最短路径问题

注意事项:

  • 用哈希表标记搜索过的字符串
  • 对元素字符串一位一位遍历,修改成ACGT其中一个,这样即可枚举出所以变化情况
  • 枚举出的字符串,符合基因库且为搜索过,加入队列
  • 基因库的字符串也丢入哈希表,即可快速判断

代码实现

class Solution {
public:int minMutation(string startGene, string endGene, vector<string>& bank){string s = "ACGT";unordered_set<string> hash(bank.begin(), bank.end());   //基因库unordered_set<string> vis;  //是否搜索过if(!hash.count(endGene)){return -1;}if(startGene == endGene){return 0;}queue<string> q;q.emplace(startGene);vis.emplace(startGene);int ret = 0;while(q.size()){ret++;int sz = q.size();while(sz--){string t = q.front();q.pop();for(int i = 0; i < 8; i++){string tmp = t; for(int j = 0; j < 4; j++){tmp[i] = s[j];if(hash.count(tmp) && !vis.count(tmp)){if(tmp == endGene){return ret;}q.emplace(tmp);vis.emplace(tmp);}}}}}return -1;}
};

127. 单词接龙

题目链接: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.emplace(beginWord);vis.emplace(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.emplace(tmp);vis.emplace(tmp);}}}}}return 0;}
};

675. 为高尔夫比赛砍树

题目链接:675. 为高尔夫比赛砍树

题目解析

给我们一个m*n的矩阵:

  • 0表示障碍,无法触碰
  • 1表示地面,可以行走
  • >1的表示有树,可以行走,数值表示树的高度

每次一个上下左右移动一步,如果遇到树,可以决定是否砍伐,砍完为1
砍伐树的顺序必须由低向高砍伐,比如说树的高度有3, 2, 6, 4, 5(树的高度都不同,切至少要砍到一棵树),砍伐的顺序必须是2, 3, 4, 5, 6

从下标[0, 0]出发,返回砍完所有树需要走的最小次数

算法原理

这里就求出每次要到达要砍位置的最短距离即可,即转换成了若干个迷宫问题了

这里还需要知道具体路径顺序,采用一个二维数组,记录位置,然后排一下序

image-20240917220748686

代码实现

class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m = 0;int n = 0;int cutOffTree(vector<vector<int>>& forest){m = forest.size();n = forest[0].size();vector<pair<int, int>> trees;for(int i = 0; i < m; i++){for(int j = 0; j < n; 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];});//砍树int bx = 0;int by = 0;int ret = 0;for(auto& [a, b] : trees){int step = bfs(forest, bx, by, a, b);if(step == -1)  return -1;ret += step;bx = a;by = b;}return ret;}bool vis[51][51];int bfs(vector<vector<int>>& f, int begin_x, int begin_y, int end_x, int end_y){if(begin_x == end_x && begin_y == end_y)    return 0;queue<pair<int, int>> q;memset(vis, 0, sizeof(vis));q.push({begin_x, begin_y});vis[begin_x][begin_y] = 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 && y >= 0 && x < m && y < n && f[x][y] && !vis[x][y]){if(x == end_x && y == end_y){return step;}q.push({x, y});vis[x][y] = true;}}}}return -1;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring-IOC容器-ApplicationContext

IOC:Inversion of Control 控制反转&#xff0c;是一种设计原则&#xff0c;spring 中通过DI&#xff08;dependency Injection&#xff09;来具体实现。 比如原本对象的实例化&#xff0c;是通过程序主动New出来&#xff0c;IOC中的对象实例交给Spring框架来实例化&#xff0…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0917)

七、引入 element-ui 组件库 官方文档&#xff1a; https://element-plus.org/zh-CN/ 安装 $ pnpm add element-plus自动按需&#xff1a; 安装插件 pnpm add -D unplugin-vue-components unplugin-auto-import然后把下列代码插入到你的 Vite 或 Webpack 的配置文件中 ..…

maxcompute使用篇

文章目录 maxcompute使用篇1.mongoDB与maxcompute 进行数据同步1.1 基本类型的数据1.2部分复杂类型的数据 2.maxcompute中复杂数据类型解析2.1 get_json_object2.2 json_tuple2.3 处理json几种失效的情况:2.4 STR_TO_MAP、MAP_KEYS2.5 regexp_replace2.6 FROM_JSON2.7 nvl2.8 t…

【Hot100】LeetCode—51. N 皇后

目录 1- 思路题目识别回溯 2- 实现⭐51. N 皇后——题解思路 3- ACM 实现 原题链接&#xff1a;51. N 皇后 1- 思路 题目识别 识别1 &#xff1a;给定一个整数 n &#xff0c;求解如何放置棋子的问题。 回溯 回溯三部曲 1- 回溯参数和返回值 传参 cheeseBoard、n、row 传递…

C语言:刷题日志(1)

一.阶乘计算升级版 本题要求实现一个打印非负整数阶乘的函数。 其中n是用户传入的参数&#xff0c;其值不超过1000。如果n是非负整数&#xff0c;则该函数必须在一行中打印出n!的值&#xff0c;否则打印“Invalid input”。 首先&#xff0c;知道阶乘是所有小于及等于该数的…

Solidity优质例子(一)食品溯源智能合约

这个智能合约FoodInfoItem的功能是管理食品的追溯信息&#xff0c;包括食品在不同阶段的流转、质量记录、消费者评分等。它通过区块链记录食品的生产、分销和销售过程&#xff0c;确保每一环节的透明和不可篡改性。 实际生活中的用途&#xff1a; 食品安全和质量控制&#xff1…

实时数仓3.0DWD层

实时数仓3.0DWD层 DWD层设计要点&#xff1a;9.1 流量域未经加工的事务事实表9.1.1 主要任务9.1.2 思路9.1.3 图解9.1.4 代码 9.2 流量域独立访客事务事实表9.2.1 主要任务9.2.2 思路分析9.2.3 图解9.2.4 代码 9.3 流量域用户跳出事务事实表9.3.1 主要任务9.3.2 思路分析9.3.3 …

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一&#xff0c;地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址&#xff0c;把整个机器内存比作一个酒店&#xff0c;内存单元就是这个酒店的各个房间&#xff0c;给这些房间编的门牌号&#xff0c;类比回来就是内存单元的物理地址 在第一篇介绍debug的…

替换 Oracle ,江河信息用 TDengine 解决高基数查询写入问题

在数字经济快速发展的背景下&#xff0c;智慧水利作为重要的基础设施之一&#xff0c;正逐步成为提升水资源管理效率、优化生态环境的重要力量。江西省水投江河信息技术有限公司&#xff08;以下简称“江河信息”&#xff09;作为高新技术国有企业&#xff0c;坚定致力于打造数…

【 html+css 绚丽Loading 】 000052 璇玑转轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…

Golang | Leetcode Golang题解之第404题左叶子之和

题目&#xff1a; 题解&#xff1a; func isLeafNode(node *TreeNode) bool {return node.Left nil && node.Right nil }func sumOfLeftLeaves(root *TreeNode) (ans int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {node : q[0]q q[1:]if no…

springbootadmin源码编译修改001_node版本管理工具nvm_任意切换node版本_没有成功记录过程---VUE工作笔记0026

由于项目需要对springbootadmin的源码进行编译和修改. 但是springbootadmin的源码编译很麻烦,主要是由于,springbootadmin-server-ui这个项目,因为他是一个前后端分离的 vue项目,而且是使用 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.12 首先去下载,发…

无人机培训机构技术股份合作探讨

随着无人机技术的飞速发展&#xff0c;其在航拍、农业、物流、环境监测、应急救援等多个领域展现出巨大潜力&#xff0c;市场对无人机专业人才的需求急剧增加。鉴于此&#xff0c;多家致力于无人机培训教育的机构决定携手合作&#xff0c;通过技术股份合作模式&#xff0c;共同…

C++二叉搜索树学习

目录 一、二叉搜索树概念 二、二叉搜索树的性能分析 三、二叉搜索树的构建 一、二叉搜索树概念 二叉搜索树又叫做二叉排序树&#xff0c;它可以是一颗空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若该树的左子树不为空&#xff0c;那么左子树上的任一节点都小…

【Google Chrome Windows 64 version及 WebDriver 版本】

最近升级到最新版本Chrome后发现页面居然显示错乱实在无语, 打算退回原来的版本, 又发现官方只提供最新的版本下载, 为了解决这个问题所有收集了Chrome历史版本的下载地址分享给大家. Google Chrome Windows version 64 位 VersionSize下载地址Date104.0.5112.10282.76 MBhtt…

【HTML】元素的分类(块元素、行内元素、行内块元素)

元素的分类 块元素行内元素行内块元素转换 块元素 独占一行&#xff0c;宽度默认为容器的100%&#xff0c;可以设置宽、高、行高、内外边距&#xff1b;布局时&#xff0c;块元素可以包含块元素和行内元素 <div>div</div><p>p</p><h3>h1-h6</…

C++——内存管理

目录 引言 C/C的内存分布 C语言中动态内存管理方式 C内存管理方式 1.new/delete操作内置类型 2.new与delete操作自定义类型 operator new与operator delete函数 new与delete的实现 1.内置类型 2.自定义类型 定位new表达式 malloc/free和new/delete的区别 结束语 引…

关于Spring Cloud Gateway中 Filters的理解

Spring Cloud Gateway中 Filters的理解 Filters Filters拦截器的作用是&#xff0c;对请求进行处理 可以进行流量染色 ⭐增加请求头 例子 spring:cloud:gateway:routes:- id: add_request_header_routeuri: http://localhost:8123predicates:- Path/api/**filters:- AddR…

Redis的缓存穿透、缓存雪崩、缓存击穿怎么解决

Redis在实际使用中是会遇到很多问题的&#xff0c;例如今天说到的缓存穿透、缓存雪崩、缓存击穿。 缓存穿透&#xff1a; 缓存穿透是指客户端请求的数据在redis缓存和数据中都不存在&#xff0c;这样缓存永远都不会生效&#xff0c;这些请求都会打到数据库当中&#xff0c;对…

MySQL_数据类型简介

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…