【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;污水中的有害物质可能会对采样设备和人员造成损害…

嘎嘎嘎嘎嘎嘎嘎

☞ 通用计算机启动过程 1️⃣一个基础固件&#xff1a;BIOS 一个基础固件&#xff1a;BIOS→基本IO系统&#xff0c;它提供以下功能&#xff1a; 上电后自检功能 Power-On Self-Test&#xff0c;即POST&#xff1a;上电后&#xff0c;识别硬件配置并对其进行自检&#xff0c…

预处理详解

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

【LeetCode-139】单词拆分(回溯动归)

目录 题目描述 解法1&#xff1a;记忆回溯 代码实现 解法2&#xff1a;动态规划 代码实现 题目链接 题目描述 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 说明&#xff1a; 拆分…

Mybatis的一些工具类

** 1.实现了Interceptor接口&#xff0c;并实现了两个拦截方法&#xff1a;update和query。当Mybatis执行update或query语句时&#xff0c;会自动调用intercept法。intercept方法首先获取当前执行的SQL语句&#xff0c;并计算执行该SQL语句所需的时间。然后&#xff0c;它将执行…

【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;往往是业务方通过上层数据报表发现数据…

C++中线程的创建

线程创建 引言为什么要使用线程线程的创建使用函数指针示例运行结果使用类对象示例运行结果使用lambda表达式示例运行结果使用带参数的函数作为线程处理函数示例运行结果使用类成员函数示例运行结果引言 在学习C++的过程中,线程的使用作为一个非常重要的部分,也是在复杂项目…

aop实现统一处理日志

使用 AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;可以很方便地实现统一处理日志的功能&#xff0c;而不需要修改现有的业务代码。下面是使用 AOP 实现统一处理日志的一般步骤&#xff1a; 定义日志切面&#xff08;Aspect&#xff09;&am…

SpringBoot中日期的格式化处理

目录 1 前言 2 方法 2.1 添加JsonFormat注解 2.2 拓展SpringMVC的消息转化器 2.2.1 编写对象映射器 2.2.2 web层配置类中拓展消息转化器 1 前言 为了符合我们日常的习惯&#xff0c;在对日期类数据进行返回的时候&#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;为处理多样的循环场景提供了一系列能力。无…