LeetCode:访问所有节点的最短路径【847】
LeetCode:访问所有节点的最短路径【847】
题目描述
给出 graph 为有 N 个节点(编号为 0, 1, 2, ..., N-1)的无向连通图。
graph.length = N,且只有节点 i 和 j 连通时,j != i 在列表 graph[i] 中恰好出现一次。
返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。
示例 1:
输入:[[1,2,3],[0],[0],[0]]
输出:4
解释:一个可能的路径为 [1,0,2,0,3]
示例 2:
输入:[[1],[0,2,4],[1,3,4],[2],[1,2]]
输出:4
解释:一个可能的路径为 [0,1,4,2,3]
提示:
1 <= graph.length <= 120 <= graph[i].length < graph.length
题目分析
1.拿到这个问题时,我们先进行初步分析:
分析示例,我们可以知道每个节点是可以被重复访问的,这样子就出现了一个问题,很有可能程序将陷入一个死循环,不断在某几个节点直接无线循环下去。
为了解决这个问题,我们可以使用二进制值来保存节点的访问状态:

2.该用什么算法来描述访问所有节点的问题呢?
访问所有节点其实就是一种搜索算法,只是现在我们不是搜索每个确定的节点值,而是有条件的状态搜索(比如目标状态为1111)。
题目中说,你可以在任一节点开始和停止,那每个节点都应该是搜索的一种初始状态,并且从每个节点的这个初始状态去探索其他状态,并且最终找到目标状态前,遍历了所有的可能性,是一种典型的BFS算法应用。
3.BFS算法的过程是怎么样的?
我们都知道BFS搜索的算法描述是一棵树,那么算法的第一层是每个节点,接下来每层数的扩展都算路径中的一步(因为每一层代表了所有的可能性,在这么多可能性中至少有一种是可以最终找到目标状态的),最后知道找到目标状态,返回的步骤就是最短路径。

4.二进制状态与搜索的互相作用是怎么样的?
我们说了每一次搜索都要参考二进制状态,来避免死循环。每个节点都要一张所有状态的表格,比如第一个节点的某个状态被激活了,后来在某一次搜索中又回到第一个节点,并且状态发现这个状态出现过,那么很显然,这样走下去就会死循环,我们就可以跳过这种情况。
这样会出现一个情况,同一种状态,对于不同节点来说是不一样的,对于1号节点可能是死循环,但是对与2号节点来说很可能是正常的。
5.节点与状态之间的转换是怎样的?就是从一个节点到另一个节点,状态是怎么变化的?
这里我们采用了或的方式来进行状态转换控制,比如访问0号节点的时候状态是0001,接下来要访问2号节点,那么状态就会变为(0001 | 0100 =0101)!
Java实现
package graph; import java.util.LinkedList;
import java.util.Queue; public class ShortestPathLength_847 { public int shortestPathLength(int[][] graph) {
int kAns = (1<<graph.length)-1;
Queue<Pair> q = new LinkedList<>();
int[][] visited = new int[graph.length][1<<graph.length];
for(int i=0;i<graph.length;i++)
q.offer(new Pair(i,1<<i)); int steps =0;
while (!q.isEmpty())
{
int s = q.size();
while (s-->0)
{
Pair pair = q.poll();
int n = pair.i;
int state = pair.j;
if(state==kAns)
return steps;
if(visited[n][state]==1)
continue;
visited[n][state]=1;
for(int next:graph[n])
q.offer(new Pair(next,state|(1<<next)));
}
steps++;
}
return -1;
} class Pair{
int i,j; public Pair(int i, int j) {
this.i = i;
this.j = j;
}
}
LeetCode:访问所有节点的最短路径【847】的更多相关文章
- [Swift]LeetCode847. 访问所有节点的最短路径 | Shortest Path Visiting All Nodes
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. graph.lengt ...
- 使用JSCH框架通过跳转机访问其他节点
之前搞了套远程访问ssh进行操作的代码,最近有需求,需要通过一台跳转机才能访问目标服务.在网上搜了半天,也没找到比较好的例子,就自己翻阅了下JSCH的API.但是看的云里雾里的.联想了下,端口转发的原 ...
- 访问子节点childNodes
访问子节点childNodes 访问选定元素节点下的所有子节点的列表,返回的值可以看作是一个数组,他具有length属性. 语法: elementNode.childNodes 注意: 如果选定的节点 ...
- CC10:访问单个节点的删除
题目 实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点. 给定待删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true 解法 这道题并不难,主要是题目中这句话确定 ...
- [LeetCode] 847. Shortest Path Visiting All Nodes 访问所有结点的最短路径
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. graph.lengt ...
- 使用JavaScript访问子节点方法elementNode.childNodes时,需要注意的地方
有这样一个HTML结构 <div> javascript <p>javascript</p> <div>jQuery</div> <h ...
- Traefik访问master节点不通的问题定位
问题 部署traefik到客户节点的对外访问节点后,发现日志里面报错 类似于 E0122 :: reflector.go:] k8s.io/dns/vendor/k8s.io/client-go/to ...
- [LeetCode] 完全二叉树的节点个数
题目链接: https://leetcode-cn.com/problems/count-complete-tree-nodes 难度:中等 通过率:57.4% 题目描述: 给出一个 完全二叉树 ,求 ...
- [LeetCode系列] K节点倒序问题迭代解法
给定链表和整数k, 使用in-space方法将链表按k个为一组进行倒序, 如果剩余个数不足k个则保留其原始顺序. 如给定1->2->3->4->5, k = 2, 需要返回 2 ...
随机推荐
- iOS升级经验分享
作者认为,及时关注.快速反应.覆盖测试是面对iOS系统升级时最重要的三大原则,文中还详细分析了iCloud Storage和Automatic Reference Counting这两大iOS 5新特 ...
- android的多次点击事件的实现(有源码)
三次点击事件的原理图:数组的复制(android源码的调用): 下面就是第一步: 创建long数组,里面的数字代表点击的次数. 下面是主要代码实现: system.arraycopy();里面的参数描 ...
- 【spring】spring的事务传播性 hibernate/jpa等的事务隔离性
spring的注解 @Trancational加在controller层,调用了service层的方法,service层的方法也加了@Trancational注解,这时候就出现了事务的嵌套,也就出现了 ...
- ThinkPHP创建应用的一般开发流程及实例
Thinkphp是免费开源的php框架,提供了建站所需要的各种组件,方便用户快速建设部署网站. Thinkphp简介:http://thinkphp.cn/Manual/16 官方完全开发手册:htt ...
- c 数组做为形參时 该參数退化为指针
当数组做为函数的形參的时候,该參数退化为指针,而且是无法直接求得数组的大小. 传数组给一个函数.数组类型自己主动转换为指针类型,因而传的实际是地址. void func(int array[10]) ...
- 转: 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
from: https://github.com/RubyLouvre/agate/issues/8 今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以 ...
- Win7如何自定义鼠标右键菜单 添加用记事本打开
鼠标右键用记事本打开.reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\Notepad] @="用记事本 ...
- 怎样mac上安装apk到连接数据线的手机
高大上的mac俺也用了一段时间了.不知道大家有木有同一个烦恼.曾经在win上的时候仅仅要安装了应用宝之类的手机助手.就能够双击APK,直接安装到连接数据线的手机上,非常方便哈,可是mac上不行.近期找 ...
- android 怎样单独下载一个项目
起因,"网络"不太好."比方铁通的就是不如联通的" 每次运行一边repo sync,十分蛋疼,假设不做full build无需所有下载,着急看某个项目的修改但是 ...
- 强大易用的日期和时间库 Joda Time
Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成,并且它是线程安全 ...