【数据结构与算法】不同路径 III:使用哈密尔顿路径算法实现
【数据结构与算法】不同路径 III:使用哈密尔顿路径算法实现
Java
不同路径 III
https://leetcode-cn.com/problems/unique-paths-iii/
解题思路
使用哈密尔顿路径的方法解决。
图的深度优先遍历,在遍历时通过left变量记录所有可走的方块有没有被遍历了,如果发现全部遍历过了,并且是在出口了,那么就认为我们找到了一条哈密尔顿路径,返回1,这样多个遍历路径合并的最终结果就是问题的解。有个比较神奇的地方,就是为啥只使用一次深度优先遍历就能找到所有路径?这应该归功于深度优先遍历的特点,可以尝试把深度优先遍历的遍历树画出来,每一个叶子结点到根结点的路径就是我们深度遍历到不同终点的路径了,而每个叶子结点之间的遍历互不影响~
本算法我认为有以下几点是比较特别的:
- 遍历时用到回溯思想,即遍历完了之后在本次遍历路径肯定不用再去判断是否被访问了,所以要给其他遍历路径留活路,把它设置为未访问。
- 使用left变量记录被访问的顶点的个数,不需要在判断时再去遍历isVisited数组有没有被全部访问了,这里有点奇怪的是left不需要通过减一进行回溯吗?答案是肯定的,因为我们方法传参的特性,你递归调用后在被调用方法里加了一,但是调用方法中的left不会变,因为letf是基本数据类型,不会影响到调用方法中的值。
- 巧妙利用了深度优先遍历遍历树的特性,一开始看到问题我还在想是不是要把找到的每条路径保存下来,用于后面的去重?结果发现深度遍历的遍历树中两条遍历路径是不会相互影响的,所以你只需要遍历所有的遍历树,然后把满足条件的叶子结点记录下来并累加到结果中就可以了。
本算法对递归的使用、图的深度优先遍历、图的建模和对哈密尔顿路径的理解都是不错的锻炼。
还可以尝试把所有哈密尔顿路径输出。
代码
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:使用哈密尔顿路径算法实现的更多相关文章
- 旅行商问题(TSP)、最长路径问题与哈密尔顿回路之间的联系(归约)
一,旅行商问题与H回路的联系(H回路 定义为 哈密尔顿回路) 旅行商问题是希望售货员恰好访问每个城市一次,最终回到起始城市所用的费用最低,也即判断图中是否存在一个费用至多为K的回路.(K相当于图中顶点 ...
- Leetcode 980. 不同路径 III
980. 不同路径 III 显示英文描述 我的提交返回竞赛 用户通过次数42 用户尝试次数43 通过次数46 提交次数60 题目难度Hard 在二维网格 grid 上,有 4 种类型的方格: 1 ...
- 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现
Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...
- Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III)
Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III) 深度优先搜索的解题详细介绍,点击 在二维网格 grid 上,有 4 种类型的方格: 1 ...
- [POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法)
[POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法) 题面 给出两个长度为\(n\)的序列\(B,C\),已知\(A\)和\(B\)的循环卷积为\(C\),求 ...
- [PHP]算法-二叉树中和为某一值的路径的PHP实现
二叉树中和为某一值的路径: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的li ...
- 经典算法题每日演练——第十六题 Kruskal算法
原文:经典算法题每日演练--第十六题 Kruskal算法 这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想 若存在M={0, ...
- 【啊哈!算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- 【十大算法实现之naive bayes】朴素贝叶斯算法之文本分类算法的理解与实现
关于bayes的基础知识,请参考: 基于朴素贝叶斯分类器的文本聚类算法 (上) http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.h ...
随机推荐
- 如何高效发布Android AAR包到远程Maven仓库
本文同步发布于公众号:移动开发那些事如何高效发布Android AAR包到远程Maven仓库 1 背景 在Gradle 7.0之前的版本中,maven插件是发布AAR包到远程Maven仓库的主要工具. ...
- 搭建springboot web系统
一.集成spring-data-jpa 我在实际项目中使用mybaties居多,但是个人喜欢spring-data-jpa,在 1. 添加依赖 <!-- 数据源依赖 --> <dep ...
- CDS标准视图:银行对账单抬头 I_BankStatement
视图名称:银行对账单抬头 I_BankStatement 视图类型:基础 视图代码: 点击查看代码 事务代码:FF67/ 视图结构: 字段名称 技术名称 短代码 BANKSTATEMENTSHORTI ...
- Task异常处理的坑
全局异常 TaskScheduler.UnobservedTaskException += (e, args) =>{ MessageBox.Show("ddddddddddddddd ...
- SpringBoot 集成腾讯云(对象存储、短信)
https://developer.aliyun.com/article/831473 https://blog.csdn.net/weixin_45626288/article/details/11 ...
- 微服务实战系列(八)-网关springcloud gateway自定义规则-copy
1. 场景描述 先说明下项目中使用的网关是:springcloud gateway, 因需要给各个网关服务系统提供自定义配置路由规则,实时生效,不用重启网关(重启风险大),目前已实现:动态加载自定义路 ...
- Spring Security + Redis + JWT 实现动态权限管理【前后端分离】
本篇文章环境:Spring Boot + Mybatis + Spring Security + Redis + JWT 数据库设计Web 的安全控制一般分为两个部分,一个是认证,一个是授权.认证即判 ...
- 第十三章 HashMap&HashSet源码解析
HashMap源码解析 5.1.对于HashMap需要掌握以下几点 Map的创建:HashMap() 往Map中添加键值对:即put(Object key, Object value)方法 获取Map ...
- Spaghetti pg walkthrough Intermediate
nmap ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.170.160 Starting Nmap 7.94SVN ( https://nmap.org ) a ...
- OpenStack基本介绍
本文分享自天翼云开发者社区<OpenStack基本介绍>,作者:m****n 基本介绍 OpenStack是一个开源的云计算管理平台项目,由几个主要的组件组合起来完成具体工作.OpenSt ...