当前位置: 首页 > news >正文

BFS 算法专题(三):BFS 解决边权为 1 的最短路问题

目录

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

1.1 算法原理

1.2 算法代码

2. 最小基因变化 ★★★

2.1 算法原理

2.2 算法代码

3. 单词接龙

3.1 算法原理

3.2 算法代码

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

4.1 算法原理

 4.2 算法代码


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

. - 力扣(LeetCode)

1.1 算法原理

核心问题: 图论 => 边权为1/边权相同 的最短路径问题

解法: 从起点开始, 进行 BFS 扩展, 第一次到达终点时, 扩展的层数, 就是最短的路径.

如何记录 BFS 扩展的层数呢??
--- 借助每一层中节点的数量(queue.size()), 使用变量 ret 记录扩展的层数.

1.2 算法代码

class Solution {public int nearestExit(char[][] maze, int[] entrance) {int[] dx = { 1, -1, 0, 0 };int[] dy = { 0, 0, 1, -1 };// 记录到达终点时, BFS 的层数int ret = 0;int m = maze.length, n = maze[0].length;boolean[][] check = new boolean[m][n];Queue<int[]> q = new LinkedList<>();q.offer(entrance);check[entrance[0]][entrance[1]] = true;while (!q.isEmpty()) {int size = q.size();ret++;while (size-- != 0) {int[] tmp = q.poll();int a = tmp[0], b = tmp[1];for (int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if (x >= 0 && x < m && y >= 0 && y < n && !check[x][y] && maze[x][y] == '.') {if (x == 0 || x == m - 1 || y == 0 || y == n - 1) return ret;q.offer(new int[] { x, y });check[x][y] = true;}}}}return -1;}
}

2. 最小基因变化 ★★★

. - 力扣(LeetCode)

2.1 算法原理

问题转化: 转化为 => 图论 边权为1的最短路问题

  1. 每变一个字符(基因的变化)看做一步, BFS 选出达到目标基因序列时的最短路.
  2. 注意: 不能重复搜索已经搜索过的状态
  3. 注意: 经过变化的字符串, 应该在 bank 基因库中存在
  4. 使用 哈希表 标记已经搜索过的状态
  5. 使用 哈希表 保存基因库中的字符(便于查找变化的字符串是否在基因库中)

2.2 算法代码

class Solution {public int minMutation(String startGene, String endGene, String[] bank) {Queue<String> q = new LinkedList<>();// 判断是否重复转化Set<String> check = new HashSet<>();// 判断基因库中是否存在Set<String> hash = new HashSet<>();for(String s : bank) hash.add(s);if(!hash.contains(endGene)) return -1;if(startGene.equals(endGene)) return 0;char[] change = {'A', 'C', 'G', 'T'};int ret = 0;q.offer(startGene);check.add(startGene);while(!q.isEmpty()) {int size = q.size();ret++;while(size-- != 0) {String s = q.poll();for(int i = 0; i < 8; i++) {char[] tmp = s.toCharArray();for(int j = 0; j < 4; j++) {tmp[i] = change[j];String next = new String(tmp);if(hash.contains(next) && !check.contains(next)) {if(next.equals(endGene)) return ret;check.add(next);q.offer(next);}}}}}return -1;}
}

3. 单词接龙

. - 力扣(LeetCode)

3.1 算法原理

  • 本题解法与上题解法完全一致.

  • 只不过返回值略有差异. 本题返回达到目标字符串时, 所涉及到的最少的字符串的个数(最短路 +1)

3.2 算法代码

class Solution {public int ladderLength(String beginWord, String endWord, List<String> wordList) {// 把字典中的字符串, 放到哈希表中 => 查找效率 O(1)Set<String> hash = new HashSet<>(wordList);if(!hash.contains(endWord)) return 0;int n = beginWord.length();// 判断是否重复转化Set<String> check = new HashSet<>();Queue<String> q = new LinkedList<>();int step = 0;q.offer(beginWord);check.add(beginWord);while(!q.isEmpty()) {int size = q.size();step++;while(size-- != 0) {String s = q.poll();for(int i = 0; i < n; i++) {char[] tmp = s.toCharArray();for(char ch = 'a'; ch <= 'z'; ch++) {tmp[i] = ch;String next = new String(tmp);if(hash.contains(next) && !check.contains(next)) {if(next.equals(endWord)) return step + 1;q.offer(next);check.add(next);}}}}}return 0;}
}

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

. - 力扣(LeetCode)

4.1 算法原理

  • 对砍树的顺序做好记录(所砍树的高度应从小到大), 并记录好每一颗树的位置.

  • 从起点开始, 对这些位置依次进行 BFS, 找出到达这些位置的最短路.

  • 返回到达所有位置所需最少步数之和

 4.2 算法代码

class Solution {int m, n;int[] dx = new int[] { 1, -1, 0, 0 };int[] dy = new int[] { 0, 0, 1, -1 };public int cutOffTree(List<List<Integer>> forest) {m = forest.size(); n = forest.get(0).size();List<int[]> trees = new ArrayList<>();for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (forest.get(i).get(j) > 1) trees.add(new int[] {i, j});}}// 依次需要砍的树(树的高度从小到大)Collections.sort(trees, (a, b) -> forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]));int step = 0;int curX = 0, curY = 0;for (int[] t : trees) {int x = t[0], y = t[1];int ret = bfs(x, y, curX, curY, forest);if (ret == -1) return -1;step += ret;curX = x;curY = y;}return step;}public int bfs(int x, int y, int curX, int curY, List<List<Integer>> forest) {int ret = 0;if (curX == x && curY == y) return 0;boolean[][] check = new boolean[m][n];Queue<int[]> q = new LinkedList<>();q.offer(new int[] { curX, curY });check[curX][curY] = true;while (!q.isEmpty()) {int size = q.size();ret++;while (size-- != 0) {int[] t = q.poll();int a = t[0], b = t[1];for (int k = 0; k < 4; k++) {int i = a + dx[k], j = b + dy[k];if (i >= 0 && i < m && j >= 0 && j < n && forest.get(i).get(j) != 0 && !check[i][j]) {if (forest.get(i).get(j) == forest.get(x).get(y))return ret;q.offer(new int[] { i, j });check[i][j] = true;}}}}return -1;}
}

END


http://www.mrgr.cn/news/74666.html

相关文章:

  • hive的tblproperties支持修改的属性
  • 动手学深度学习10.1. 注意力提示-笔记练习(PyTorch)
  • 浅谈:基于三维场景的视频融合方法
  • 谁会从新技术中受益?
  • 论文阅读《机器人状态估计中的李群》
  • SAP ABAP开发学习——function alv复选框设置
  • PostgreSQL 一键安装部署脚本化
  • 【算法】【优选算法】前缀和(上)
  • SQLI LABS | Less-45 POST-Error Based-String-Stacked-Bilnd
  • Python防检测之鼠标移动轨迹算法
  • 英语中常用的两者及以上的词表示,并且比较它们
  • Bootstrap 5 轮播
  • Rust 数据类型
  • 鸿蒙北向开发环境安装指南
  • 后台管理系统的通用权限解决方案(十四)基于JWT实现登录功能
  • 电路板维修入门之集成电路的检测方法篇
  • 苹果低价版Vision Pro 推迟至2027年发布:XR领域的变局与挑战
  • 【Oracle篇】掌握SQL Tuning Advisor优化工具:从工具使用到SQL优化的全方位指南(第六篇,总共七篇)
  • 开发指南079-数据冗余
  • Java 中的字符输入流详解
  • Vue3 常见的 9 种组件通信机制
  • SpringBoot开发——整合OpenCSV 实现数据导入导出-CSV
  • 《.addClass()》
  • 【Hive】【HiveQL】【大数据技术基础】 作业三 数据仓库Hive的使用
  • 107、Python并发编程:失败自动重试,一次搞懂简单实用的Timer
  • 网络安全开发详解与python实现