【数据结构与算法】不同路径 III:使用哈密尔顿路径算法实现

Java

不同路径 III

https://leetcode-cn.com/problems/unique-paths-iii/

解题思路

使用哈密尔顿路径的方法解决。

图的深度优先遍历,在遍历时通过left变量记录所有可走的方块有没有被遍历了,如果发现全部遍历过了,并且是在出口了,那么就认为我们找到了一条哈密尔顿路径,返回1,这样多个遍历路径合并的最终结果就是问题的解。有个比较神奇的地方,就是为啥只使用一次深度优先遍历就能找到所有路径?这应该归功于深度优先遍历的特点,可以尝试把深度优先遍历的遍历树画出来,每一个叶子结点到根结点的路径就是我们深度遍历到不同终点的路径了,而每个叶子结点之间的遍历互不影响~

本算法我认为有以下几点是比较特别的:

  1. 遍历时用到回溯思想,即遍历完了之后在本次遍历路径肯定不用再去判断是否被访问了,所以要给其他遍历路径留活路,把它设置为未访问。
  2. 使用left变量记录被访问的顶点的个数,不需要在判断时再去遍历isVisited数组有没有被全部访问了,这里有点奇怪的是left不需要通过减一进行回溯吗?答案是肯定的,因为我们方法传参的特性,你递归调用后在被调用方法里加了一,但是调用方法中的left不会变,因为letf是基本数据类型,不会影响到调用方法中的值。
  3. 巧妙利用了深度优先遍历遍历树的特性,一开始看到问题我还在想是不是要把找到的每条路径保存下来,用于后面的去重?结果发现深度遍历的遍历树中两条遍历路径是不会相互影响的,所以你只需要遍历所有的遍历树,然后把满足条件的叶子结点记录下来并累加到结果中就可以了。

本算法对递归的使用、图的深度优先遍历、图的建模和对哈密尔顿路径的理解都是不错的锻炼。

还可以尝试把所有哈密尔顿路径输出。

代码

class Solution {
boolean[][] isVisited; // 访问数组
int[][] grid; // 格子的引用
int R, C; // 行数,列数
int start, end; // 开始位置,结束位置 int[][] dir4 = { // 上,下,左,右 4方向变量
{1,0},
{0,-1}, {0,1},
{-1,0}
}; public int uniquePathsIII(int[][] grid) {
this.grid = grid; R = grid.length; // 行
C = grid[0].length; // 列 isVisited = new boolean[R][C]; int left = 0;
// 扫描整个地图,判断一共有多少个可以走的格子,获取起点和终点
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (grid[i][j] == 0) {
left++;
} else if (grid[i][j] == 1) {
start = i * C + j;left++;
} else if (grid[i][j] == 2) {
end = i * C + j;left++;
}
}
} // 深度优先遍历来获取路径数量
return dfs(start, left);
} private int dfs(int v, int left) {
int x = v / C;
int y = v % C; isVisited[x][y] = true;
left--; if (left == 0) {
isVisited[x][y] = false; // 回溯,给其他路径留活路
if(v == end) {
return 1;
}
return 0; // 找到了一条哈密尔顿路径
} int res = 0;
// 获取相邻顶点
for (int[] ints : dir4) {
int x1 = x + ints[0];
int y1 = y + ints[1];
if (x1 >= 0 && y1 >= 0 && x1 < R && y1 < C && grid[x1][y1] != -1 && !isVisited[x1][y1]) {
res += dfs(x1 * C + y1, left);
}
} isVisited[x][y] = false; // 回溯
return res;
}
}

【数据结构与算法】不同路径 III:使用哈密尔顿路径算法实现的更多相关文章

  1. 旅行商问题(TSP)、最长路径问题与哈密尔顿回路之间的联系(归约)

    一,旅行商问题与H回路的联系(H回路 定义为 哈密尔顿回路) 旅行商问题是希望售货员恰好访问每个城市一次,最终回到起始城市所用的费用最低,也即判断图中是否存在一个费用至多为K的回路.(K相当于图中顶点 ...

  2. Leetcode 980. 不同路径 III

    980. 不同路径 III  显示英文描述 我的提交返回竞赛   用户通过次数42 用户尝试次数43 通过次数46 提交次数60 题目难度Hard 在二维网格 grid 上,有 4 种类型的方格: 1 ...

  3. 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  4. Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III)

    Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III) 深度优先搜索的解题详细介绍,点击 在二维网格 grid 上,有 4 种类型的方格: 1 ...

  5. [POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法)

    [POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法) 题面 给出两个长度为\(n\)的序列\(B,C\),已知\(A\)和\(B\)的循环卷积为\(C\),求 ...

  6. [PHP]算法-二叉树中和为某一值的路径的PHP实现

    二叉树中和为某一值的路径: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的li ...

  7. 经典算法题每日演练——第十六题 Kruskal算法

    原文:经典算法题每日演练--第十六题 Kruskal算法 这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想 若存在M={0, ...

  8. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  9. 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  10. 【十大算法实现之naive bayes】朴素贝叶斯算法之文本分类算法的理解与实现

    关于bayes的基础知识,请参考: 基于朴素贝叶斯分类器的文本聚类算法 (上) http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.h ...

随机推荐

  1. 如何快速的开发一个完整的iOS直播app(播放篇)

    作者:袁峥链接:https://www.jianshu.com/p/7b2f1df74420来源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 开发一款直播app,集成ij ...

  2. RockyLinux9编译安装MySQL5.7

    Linux版本: Rocky Linux release 9.5 (Blue Onyx) 1.下载 打开MySQL-Community-Server官方下载页面:https://downloads.m ...

  3. 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!

    写在前面 最近,DeepSeek 发布的推理大模型 DeepSeek - R1 ,可以说是AI大模型领域杀出的一匹黑马.它在国外大模型排名 Arena 上成绩惊人,基准测试位列全类别大模型第三,在风格 ...

  4. 同步工具-腾讯EMR表治理工具安装使用

    一.安装 1.root用户上传文件 cd wangrz -bey luoshu-1.0-bin.tar.gz 2.解压文件到服务目录 重新安装洛书需执行:rm -rf /usr/local/servi ...

  5. Luogu P10997 Partition 题解 [ 蓝 ] [ 分割线 dp ]

    Partition:一道 dp 神题,用到了以轮廓线的轨迹来做 dp 的技巧,和敲砖块这题的状态设计有点相似. 观察 首先观察样例,发现整张图可以看作是被两条线分隔开的.同时每个颜色的四个方向上又存在 ...

  6. C#/.NET/.NET Core优秀项目和框架2025年1月简报

    前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的详细介绍.功能特点.使用方式以及部分功能 ...

  7. 在线客服的独立产品之路:如何将复杂的 .NET 系统打包到 Docker 镜像,使之能一键上线

    我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统.陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户,在这个过程中,我也积累了不少如何开发运营 ...

  8. Scrapy 入门基础

    原文学习参考链接:https://blog.csdn.net/u011054333/article/details/70165401 问题解决参考链接:https://blog.csdn.net/du ...

  9. 【杂谈】主键ID如何选择——自增数 OR UUID?

    1.生成位置如何影响选择? 数据库往返时间 使用自增数时,ID是由数据库在执行INSERT操作时生成的:而UUID则可以在应用层生成. 考虑这样的场景: 一个方法需要插入A和B两个实体.其中B的数据需 ...

  10. linux命令行连接wifi

    linux命令行连接wifi 1.安装nmcli sudo apt-get install nmcli 2.查看网络设备 sudo nmcli dev 3.开启wifi sudo nmcli r wi ...