【数据结构与算法】不同路径 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. 记录以下uniapp写小程序然后进行图片上传压缩

    今天记录一下uniapp写小程序上传图片压缩的功能 首先定义上传图片的方法 然后res.tempFilePath[0]就是图片的临时路径 其次定义压缩图片然后获取压缩后图片大小的方法,方法使用canv ...

  2. SpringMvc-初识

    ---------------------------------------------------------------- 1.环境搭建 1.1 jar包 <spring.version& ...

  3. CPU 性能优化总结

    在Linux系统中,由于成本的限制,往往会存在资源上的不足,例如 CPU.内存.网络.IO 性能.本文,就对 Linux 进程和 CPU 的原理进行分析,总结出 CPU 性能优化的方法. 1. 分析手 ...

  4. Java注意事项

    阅读目录 一.Comparable简介 二.Comparator简介 三.Comparable和Comparator区别比较 一.Comparable简介 Comparable是排序接口.若一个类实现 ...

  5. Integer包装类中的IntegerCache结构

    public void test3() { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i = ...

  6. 搭建个人AI知识库-DIFY

    前提 本地目前没有显卡,只能用cpu刚. 如果不想自己搭建本地模型,完全可以掏钱使用现成的API即可. 需要了解一些docker知识 搭建本地模型 环境 os: archlinux 内存: 32g c ...

  7. 云主机CPU和内存配比:优化资源分配的关键

    本文分享自天翼云开发者社区<云主机CPU和内存配比:优化资源分配的关键>,作者:每日知识小分享 随着云计算技术的快速发展,云主机已经成为了许多企业和个人用户首-选的计算解决方案.在部署和配 ...

  8. Iceberg治理服务Amoro---配置Prometheus + Grafana看板

    一.基础资料 1.mac安装Prometheus + Grafana https://www.cnblogs.com/robots2/p/18689540 2.配置文档 https://amoro.a ...

  9. 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!

    1 大人,时代变了! 赶快把自有业务的本地AI"模型"训练起来! 1.1 背景   目前AI已经大行其道,chatGPT.DeepSeek等如雨后春笋般涌现出来,笔者做为一个守旧派 ...

  10. 安川YASKAWA工业机器人板卡维修策略

    一.安川YASKAWA工业机器人板卡识别故障症状 首先,需要准确识别电路板故障的症状.这通常包括安川YASKAWA机器人操作不稳定.错误代码频繁出现.某些功能失效或整体性能下降等.通过仔细观察和诊断, ...