【LeetCode】无权图的最短路精选7题——单源、多源

目录

无权图的单源最短路问题:

1. 迷宫中离入口最近的出口(中等)

2. 最小基因变化(中等)

3. 单词接龙(困难)

4. 为高尔夫比赛砍树(困难)

无权图的多源最短路问题:

1. 01矩阵(中等)

2. 地图中的最高点(中等)

3. 地图分析(中等)


无权图的单源最短路问题:

使用单源BFS可以求解无权图的单源最短路问题,这是由BFS总是按照距离由近到远来遍历图中每个顶点的性质决定的。

1. 迷宫中离入口最近的出口(中等)

class Solution {
public:int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {int m = maze.size();int n = maze[0].size();vector<vector<bool>> visited(m, vector<bool>(n));int ans = 0;// 坐标上下左右的偏移量int dr[4] = { -1,1,0,0 };int dc[4] = { 0,0,-1,1 };queue<pair<int, int>> q;// 起始坐标入队并标记q.push({entrance[0], entrance[1]});visited[entrance[0]][entrance[1]] = true;while (!q.empty()){// 要向外拓展一层,步数++ans++;int count = q.size(); // 本层坐标点的个数for (int i = 0; i < count; i++){// 队头出队auto [row, col] = q.front();q.pop();// 判断刚才出队的坐标上下左右是否满足条件,再判断是否到达出口,到达则直接返回,没到达则入队并标记for (int j = 0; j < 4; j++){int r = row + dr[j];int c = col + dc[j];if (r >= 0 && r < m && c >= 0 && c < n && maze[r][c] == '.' && !visited[r][c]){if (r == 0 || r == m - 1 || c == 0 || c == n - 1) // 到达出口return ans;q.push({r, c});visited[r][c] = true;}}}}return -1;}
};

2. 最小基因变化(中等)

将距离为1(变化了一个字符)的字符串连接起来构成一个无权图,求start到end的最短路。

class Solution {
public:int minMutation(string startGene, string endGene, vector<string>& bank) {unordered_set<string> hash(bank.begin(), bank.end()); // 哈希表记录基因库中的字符串unordered_set<string> visited; // 标记字符串是否被访问过string change = "ACGT";if (startGene == endGene)return 0;if (!hash.count(endGene))return -1;int ans = 0;queue<string> q;// 起始字符串入队并标记q.push(startGene);visited.insert(startGene);while (!q.empty()){// 要向外拓展一层,步数++ans++;int count = q.size(); // 本层字符串的个数for (int i = 0; i < count; i++){// 队头出队string cur = q.front();q.pop();// 判断刚才出队的字符串只改变一个字符后是否满足条件,再判断是否到达end,到达则直接返回,没到达则入队并标记for (int i = 0; i < 8; i++){string tmp = cur;for (int j = 0; j < 4; j++){tmp[i] = change[j];if (hash.count(tmp) && !visited.count(tmp)){if (tmp == endGene) // 到达endreturn ans;q.push(tmp);visited.insert(tmp);}}}}}return -1;}
};

3. 单词接龙(困难)

和上一题“最小基因变化”类似,区别是上一题求步数,本题求最短路的顶点数。

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string> hash(wordList.begin(), wordList.end()); // 哈希表记录字典中的单词unordered_set<string> visited; // 标记单词是否被访问过if (!hash.count(endWord))return 0;int ans = 1;queue<string> q;// 起始单词入队并标记q.push(beginWord);visited.insert(beginWord);while (!q.empty()){// 要向外拓展一层,顶点数++ans++;int count = q.size(); // 本层单词的个数for (int i = 0; i < count; i++){// 队头出队string cur = q.front();q.pop();// 判断刚才出队的单词只改变一个字符后是否满足条件,再判断是否到达end,到达则直接返回,没到达则入队并标记for (int i = 0; i < cur.size(); i++){string tmp = cur;for (char ch = 'a'; ch <= 'z'; ch++){tmp[i] = ch;if (hash.count(tmp) && !visited.count(tmp)){if (tmp == endWord) // 到达endreturn ans;q.push(tmp);visited.insert(tmp);}}}}}return 0;}
};

4. 为高尔夫比赛砍树(困难)

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7

给树按从小到大排序,求顺序相邻的树的最短路。

class Solution {
public: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 beginr = 0;int beginc = 0;int ans = 0;for (auto& [endr, endc] : trees){int step = bfs(forest, beginr, beginc, endr, endc);if (step == -1)return -1;ans += step;beginr = endr;beginc = endc;}return ans;}private:int bfs(vector<vector<int>>& forest, int beginr, int beginc, int endr, int endc){if (beginr == endr && beginc == endc)return 0;vector<vector<bool>> visited(m, vector<bool>(n)); // 标记坐标是否被访问过int ans = 0;queue<pair<int, int>> q;// 起始坐标入队并标记q.push({beginr, beginc});visited[beginr][beginc] = true;while (!q.empty()){// 要向外拓展一层,步数++ans++;int count = q.size(); // 本层坐标点的个数for (int i = 0; i < count; i++){// 队头出队auto [row, col] = q.front();q.pop();// 判断刚才出队的坐标上下左右是否满足条件,再判断是否到达end,到达则直接返回,没到达则入队并标记for (int j = 0; j < 4; j++){int r = row + dr[j];int c = col + dc[j];if (r >= 0 && r < m && c >= 0 && c < n && forest[r][c] && !visited[r][c]){if (r == endr && c == endc) // 到达endreturn ans;q.push({r, c});visited[r][c] = true;}}}}return -1;}// 坐标上下左右的偏移量int dr[4] = { -1,1,0,0 };int dc[4] = { 0,0,-1,1 };int m;int n;
};

无权图的多源最短路问题:

使用多源BFS可以求解无权图的多源最短路问题,将所有的源点当成一个“超级源点”,问题就变成了单源最短路问题。

1. 01矩阵(中等)

以所有的0为源点开始BFS。

距离数组dist最开始全部初始化为-1,表示没有被访问过,后续要修改成距离(步数)。所以,首先,我们不用创建visited数组标记坐标有没有被访问过;其次,不用创建step变量记录步数,并且不用计算本层坐标点的个数count,也就是说不用确定坐标点是在第几层。

class Solution {
public:vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int m = mat.size();int n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1)); // 全部初始化为-1// 坐标上下左右的偏移量int dr[4] = { -1,1,0,0 };int dc[4] = { 0,0,-1,1 };queue<pair<int, int>> q;// 所有的源点入队并修改距离为0for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){if (mat[i][j] == 0){q.push({i, j});dist[i][j] = 0;}}}while (!q.empty()){// 队头出队auto [row, col] = q.front();q.pop();// 判断刚才出队的坐标上下左右是否满足条件,满足条件则入队并修改距离for (int j = 0; j < 4; j++){int r = row + dr[j];int c = col + dc[j];if (r >= 0 && r < m && c >= 0 && c < n && dist[r][c] == -1){q.push({r, c});dist[r][c] = dist[row][col] + 1;}}}return dist;}
};

2. 地图中的最高点(中等)

水域格子的值是确定的,为0,以所有的0为源点开始BFS,和上一题“01矩阵”一模一样。

class Solution {
public:vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {int m = isWater.size();int n = isWater[0].size();vector<vector<int>> dist(m, vector<int>(n, -1)); // 全部初始化为-1// 坐标上下左右的偏移量int dr[4] = { -1,1,0,0 };int dc[4] = { 0,0,-1,1 };queue<pair<int, int>> q;// 所有的源点入队并修改距离为0for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){if (isWater[i][j] == 1){q.push({i, j});dist[i][j] = 0;}}}while (!q.empty()){// 队头出队auto [row, col] = q.front();q.pop();// 判断刚才出队的坐标上下左右是否满足条件,满足条件则入队并修改距离for (int j = 0; j < 4; j++){int r = row + dr[j];int c = col + dc[j];if (r >= 0 && r < m && c >= 0 && c < n && dist[r][c] == -1){q.push({r, c});dist[r][c] = dist[row][col] + 1;}}}return dist;}
};

3. 地图分析(中等)

以所有的陆地单元格为源点开始BFS,陆地单元格对应在距离数组dist中的值为0,和“01矩阵”、“地图中的最高点”都是一样的题。

class Solution {
public:int maxDistance(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1)); // 全部初始化为-1int ans = -1;// 坐标上下左右的偏移量int dr[4] = { -1,1,0,0 };int dc[4] = { 0,0,-1,1 };queue<pair<int, int>> q;// 所有的源点入队并修改距离为0for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){if (grid[i][j] == 1){q.push({i, j});dist[i][j] = 0;}}}while (!q.empty()){// 队头出队auto [row, col] = q.front();q.pop();// 判断刚才出队的坐标上下左右是否满足条件,满足条件则入队并修改距离for (int j = 0; j < 4; j++){int r = row + dr[j];int c = col + dc[j];if (r >= 0 && r < m && c >= 0 && c < n && dist[r][c] == -1){q.push({r, c});dist[r][c] = dist[row][col] + 1;ans = max(ans, dist[r][c]);}}}return ans;}
};

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

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

相关文章

疾控中心污水采样过程中会遇到哪些困难

在疾控中心的污水采样过程中&#xff0c;可能会遇到多种困难。 首先&#xff0c;污水的成分可能非常复杂&#xff0c;包括各种细菌、病毒、寄生虫、重金属、化学物质等&#xff0c;这给采样带来了很大的挑战。其次&#xff0c;污水中的有害物质可能会对采样设备和人员造成损害…

预处理详解

目录 预定义符号介绍 ​编辑 预处理指令 #define #define 定义标识符 #define 定义宏 #define 替换规则 #define中#和##的使用 带副作用的宏参数 宏和函数的对比 命令行定义 预处理指令 #undef 预处理指令 #include 头文件被包含的方式&#xff1a; 本地文件包含 …

【Unity】【VR开发】Unity云同步功能使用心得

【背景】 有时出差,旅行等等也带着电脑,晚上想要继续编辑项目,就需要用到云同步功能。目前实践下来,发现有些内容可以同步,有些内容则是不可以同步的,总结如下。 【如何云同步一个本地项目】 UnityHub的项目面板中有两个选项卡:项目和云端项目。 鼠标挪动到想要云同步…

c++类和对象新手保姆级上手教学(中)

前言&#xff1a; 类和对象中篇&#xff0c;这里讲到的前4个默认成员函数&#xff0c;是类和对象中的重难点&#xff0c;许多资料上的讲法都非常抽象&#xff0c;难以理解&#xff0c;所以我作出这篇总结&#xff0c;分享学习经验&#xff0c;以便日后复习。 目录 6个默认成员…

土壤墒情监测站的工作原理

TH-TS600土壤墒情自动监测站是一种用于自动检测土壤墒情的仪器&#xff0c;它可以实时监测土壤的水分含量和温度&#xff0c;并将数据传输到数据中心或监测中心进行分析和处理。 土壤墒情自动监测站通常由传感器、数据采集器、数据传输设备和数据处理软件等部分组成。传感器是…

Laravel02 路由基本概念和用法 给视图传递请求参数

Laravel02 路由基本概念和用法 1. 路由的基本概念2. 给视图传递请求参数 1. 路由的基本概念 routes文件夹下的web.php是用来定义路由规则的。 自己定义一个路径 2. 给视图传递请求参数 在laravel里使用一个辅助函数request来快速获取请求参数

NX/UG二次开发—CAM—平面铣边界准确设置方法

大家在对平面铣设置边界时&#xff0c;经常遇到边界方向与自己期望的不一致&#xff0c;有些人喜欢用检查刀路是否过切来判断&#xff0c;但是对于倒角、负余量等一些情况&#xff0c;刀路本来就是过切的。对于多边界&#xff0c;可以根据选择的曲线来起点和面的方向来确定&…

Camera2 createCaptureSession源码分析

当应用调用CameraManager#openCamera获取到已打开的camera设备后&#xff0c;会调用createCaptureSession方法来完成camera stream创建和stream的相关配置。在createCaptureSession方法中&#xff0c;首先将应用的surfaces信息封装成可跨binder传递的OutputConfiguration对象&a…

ACE 中的Active Object模式

Active Object 设计模式&#xff1a; 1&#xff09; 根据对象被调用的方式&#xff0c;可以将对象分为两类: Passive Object和Active Object。Passive 和 Object和调用者在同一个线程中&#xff0c;这就是我们通常所用的函数调用。而Active Object和调用在不同的线程中&#xf…

Leo赠书活动-16期 名校毕业生教材

Leo赠书活动-16期 名校毕业生教材 ✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠…

大厂的数据质量中心系统设计

日常工作中&#xff0c;数据开发上线完一个任务后并不是就可以高枕无忧&#xff0c;时常因上游链路数据异常或者自身处理逻辑的 BUG 导致产出的数据结果不可信。而问题发现可经历较长周期&#xff08;尤其离线场景&#xff09;&#xff0c;往往是业务方通过上层数据报表发现数据…

华为---RSTP(二)---RSTP基本配置示例

目录 1. 示例要求 2. 网络拓扑图 3. 配置命令 4. 测试终端连通性 5. RSTP基本配置 5.1 启用STP 5.2 修改生成树协议模式为RSTP 5.3 配置根交换机和次根交换机 5.4 设置边缘端口 6. 指定端口切换为备份端口 7. 测试验证网络 1. 示例要求 为防止网络出现环路&#xf…

【论文精读】MAE

摘要 将掩码重建任务从nlp引入到cv&#xff0c;提出非对称掩码自编码器。 框架 概述 如上图&#xff0c;本文提出掩码自编码器&#xff0c;即将给定原始信号的部分观测值的情况下重建原始信号&#xff0c;编码器将观察到的部分信号(没有掩码标记)映射到潜在表示&#xff0c;采…

Golang for 循环

从基础知识到高级技术、并发和通道 Go&#xff08;Golang&#xff09;编程语言中的“for”循环是一个基本而多功能的结构&#xff0c;用于迭代集合、重复执行代码块以及管理循环控制流。Golang的“for”循环语法简洁却强大&#xff0c;为处理多样的循环场景提供了一系列能力。无…

算法——数值算法——牛顿迭代法

目录 牛顿迭代法 一、1021: [编程入门]迭代法求平方根 牛顿迭代法 迭代法&#xff08;Iteration&#xff09;是一种通过反复递推计算来逼近解的方法。而牛顿迭代法&#xff08;Newtons method&#xff09;则是一种特定的迭代法&#xff0c;用于求解方程或函数的根、最小值、最…

MySQL数据库基础(十):DQL数据查询语言

文章目录 DQL数据查询语言 一、数据集准备 二、select查询 三、简单查询 四、条件查询 1、比较查询 2、范围查询 3、逻辑查询 4、模糊查询 5、非空查询 五、排序查询 六、聚合查询 七、分组查询与having子句 1、分组查询介绍 2、group by的使用 3、group by 聚…

【设计模式】23种设计模式笔记

设计模式分类 模板方法模式 核心就是设计一个部分抽象类。 这个类具有少量具体的方法&#xff0c;和大量抽象的方法&#xff0c;具体的方法是为外界提供服务的点&#xff0c;具体方法中定义了抽象方法的执行序列 装饰器模式 现在有一个对象A&#xff0c;希望A的a方法被修饰 …

单片机学习笔记---红外遥控红外遥控电机调速(完结篇)

目录 低电平触发中断和下降沿触发中断的区别 红外遥控 Int0.c Int.h Timer0.c Timer0.h IR.c IR.h main.c 红外遥控电机调速 Timer1.c Timer.h Motor.c Motor.h main.c 上一节讲了红外发送和接收的工作原理&#xff0c;这一节开始代码演示&#xff01; 提前说…

微信小程序-表单提交和校验

一、使用vant组件生成如下页面 二、前端代码如下 <form bindsubmit"submitForm"><view class"cell-group"><van-cell-group><van-field value"{{ title }}" label"商品名称" placeholder"请输入商品名称&qu…

Dubbo框架admin搭建

Dubbo服务监控平台&#xff0c;dubbo-admin是图形化的服务管理界面&#xff0c;从服务注册中心获取所有的提供者和消费者的配置。 dubbo-admin是前后端分离的项目&#xff0c;前端使用Vue&#xff0c;后端使用springboot。因此&#xff0c;前端需要nodejs环境&#xff0c;后端需…