【LeetCode】847. Shortest Path Visiting All Nodes 解题报告(Python)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址: https://leetcode.com/problems/shortest-path-visiting-all-nodes/description/
题目描述:
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph.
graph.length = N, and j != i is in the list graph[i] exactly once, if and only if nodes i and j are connected.
Return the length of the shortest path that visits every node. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges.
Example 1:
Input: [[1,2,3],[0],[0],[0]]
Output: 4
Explanation: One possible path is [1,0,2,0,3]
Example 2:
Input: [[1],[0,2,4],[1,3,4],[2],[1,2]]
Output: 4
Explanation: One possible path is [0,1,4,2,3]
Note:
- 1 <= graph.length <= 12
- 0 <= graph[i].length < graph.length
题目大意
在一个无向联通图中,可以从任意一点出发,找到最少需要多少步才能把所有的顶点遍历结束。每个边可以访问多次。
解题方法
方法一:BFS
话说看到这个题的第一感觉就是BFS,因为我们要找到遍历所有节点的最少步数,这个正是BFS擅长的。唯一不同的就是这个题允许从多个顶点出发,也就是说没有了固定的起点。那么需要对BFS稍微改变一点,即在初始化的时候,把所有顶点都放进队列之中,这样,每次把队列的元素pop出来一遍之后就是新的一轮循环,也就可以认为所有的节点都是同时向前迈进了一步。
这个题使用了一个的技巧,位运算。一般的BFS过程都是只保存访问过的节点即可,因为每个节点只可以使用一次,但是这个题的节点可以访问多次,那么就是说必须维护一个实时的访问了哪些节点的状态。按道理说,如果不使用位运算而是使用字典等方式保存访问过了的状态也可以,但是,看了给出的图的顶点个数只有12个,哪怕一个int都会有32个bit够用,所以可以直接使用和图中顶点数相等的位数来保存这个状态是否访问过。这个状态怎么理解?从每个顶点出发到达,所有访问过的节点是状态。也就是说这个状态是全局唯一的,每个顶点都有2 * N个状态表示它访问的其他节点。有2 ^ N个bit,每个位都代表对应的节点是否访问过。最终的状态是(1 << N) - 1,即全是1,表示所有节点都访问了。
这个visited是个二维数组,保存的是每个节点的所有状态,对于该题目的BFS,有可能有N * 2^N个状态,使用visited保存每个节点已经访问的状态,对应状态位置是0/1。
时间复杂度是O(N * (2^N)),空间复杂度是O(N * 2^N)。
class Solution(object):
def shortestPathLength(self, graph):
"""
:type graph: List[List[int]]
:rtype: int
"""
N = len(graph)
que = collections.deque()
step = 0
goal = (1 << N) - 1
visited = [[0 for j in range(1 << N)] for i in range(N)]
for i in range(N):
que.append((i, 1 << i))
while que:
s = len(que)
for i in range(s):
node, state = que.popleft()
if state == goal:
return step
if visited[node][state]:
continue
visited[node][state] = 1
for nextNode in graph[node]:
que.append((nextNode, state | (1 << nextNode)))
step += 1
return step
参考资料:
https://www.youtube.com/watch?v=Vo3OEN2xgwk
日期
2018 年 10 月 4 日 —— 一个很不容易察觉的小错误,需要总结一下坑了!
【LeetCode】847. Shortest Path Visiting All Nodes 解题报告(Python)的更多相关文章
- [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 ...
- LeetCode 847. Shortest Path Visiting All Nodes
题目链接:https://leetcode.com/problems/shortest-path-visiting-all-nodes/ 题意:已知一条无向图,问经过所有点的最短路径是多长,边权都为1 ...
- [Leetcode]847. Shortest Path Visiting All Nodes(BFS|DP)
题解 题意 给出一个无向图,求遍历所有点的最小花费 分析 1.BFS,设置dis[status][k]表示遍历的点数状态为status,当前遍历到k的最小花费,一次BFS即可 2.使用DP 代码 // ...
- leetcode 847. Shortest Path Visiting All Nodes 无向连通图遍历最短路径
设计最短路径 用bfs 天然带最短路径 每一个状态是 当前的阶段 和已经访问过的节点 下面是正确但是超时的代码 class Solution: def shortestPathLength(self, ...
- 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 ...
- 【LeetCode】222. Count Complete Tree Nodes 解题报告(Python)
[LeetCode]222. Count Complete Tree Nodes 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个 ...
- [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 ...
- 最短路径遍历所有的节点 Shortest Path Visiting All Nodes
2018-10-06 22:04:38 问题描述: 问题求解: 本题要求是求遍历所有节点的最短路径,由于本题中是没有要求一个节点只能访问一次的,也就是说可以访问一个节点多次,但是如果表征两次节点状态呢 ...
- LeetCode 821 Shortest Distance to a Character 解题报告
题目要求 Given a string S and a character C, return an array of integers representing the shortest dista ...
随机推荐
- 深入了解scanf() getchar()和gets()等函数之间的区别
scanf(), getchar()等都是标准输入函数,一般人都会觉得这几个函数非常简单,没什么特殊的.但是有时候却就是因为使用这些函数除了问题,却找不出其中的原因.下面先看一个很简单的程序: 程序1 ...
- 记一次 .NET 某化妆品 webapi 卡死分析
一:背景 1. 讲故事 10月份星球里的一位老朋友找到我,说他们公司的程序在一个网红直播带货下给弄得无响应了,无响应期间有大量的 RabbitMQ 超时,寻求如何找到根源,聊天截图我就不发了. 既然无 ...
- LInkedList总结及部分底层源码分析
LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...
- 为 Rainbond Ingress Controller 设置负载均衡
Rainbond 作为一款云原生应用管理平台,天生带有引导南北向网络流量的分布式网关 rbd-gateway.rbd-gateway 组件,实际上是好雨科技团队开发的一种 Ingress Contro ...
- 修改linux系统下mysql数据库登陆密码(密码忘记)
报错:Access denied for user 'root'@'localhost' (using password: NO) 解决方案: 1. 检查mysql服务是否启动,如果启动,关闭mysq ...
- MYSQL获取更新行的主键ID 【转】
在某些情况下我们需要向数据表中更新一条记录的状态,然后再把它取出来,但这时如果你在更新前并没有一个确认惟一记录的主键就没有办法知道哪条记录被更新了. 举例说明下: 有一个发放新手卡的程序,设计数据库时 ...
- webservice--cxf和spring结合
服务端: 实体: package entity; import java.util.Date; /*** 实体 */ public class Pojo { //温度 private String d ...
- 解决ViewPager与ScrollView 冲突
ViewPager来实现左右滑动切换tab,如果tab的某一项中嵌入了水平可滑动的View就会让你有些不爽,比如想滑动tab项中的可水平滑动的控件,却导致tab切换. 因为Android事件机制是从父 ...
- When should we write our own assignment operator in C++?
The answer is same as Copy Constructor. If a class doesn't contain pointers, then there is no need t ...
- NSMutableArray-->NSString
1.如何把NSMutableArray 转化为NSString//用字符将NSArray中的元素拼接起来 NSArray *array = [NSArray arrayWithObjects:@&qu ...