作者: 负雪明烛
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. 1 <= graph.length <= 12
  2. 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)的更多相关文章

  1. [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 ...

  2. LeetCode 847. Shortest Path Visiting All Nodes

    题目链接:https://leetcode.com/problems/shortest-path-visiting-all-nodes/ 题意:已知一条无向图,问经过所有点的最短路径是多长,边权都为1 ...

  3. [Leetcode]847. Shortest Path Visiting All Nodes(BFS|DP)

    题解 题意 给出一个无向图,求遍历所有点的最小花费 分析 1.BFS,设置dis[status][k]表示遍历的点数状态为status,当前遍历到k的最小花费,一次BFS即可 2.使用DP 代码 // ...

  4. leetcode 847. Shortest Path Visiting All Nodes 无向连通图遍历最短路径

    设计最短路径 用bfs 天然带最短路径 每一个状态是 当前的阶段 和已经访问过的节点 下面是正确但是超时的代码 class Solution: def shortestPathLength(self, ...

  5. 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 ...

  6. 【LeetCode】222. Count Complete Tree Nodes 解题报告(Python)

    [LeetCode]222. Count Complete Tree Nodes 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个 ...

  7. [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 ...

  8. 最短路径遍历所有的节点 Shortest Path Visiting All Nodes

    2018-10-06 22:04:38 问题描述: 问题求解: 本题要求是求遍历所有节点的最短路径,由于本题中是没有要求一个节点只能访问一次的,也就是说可以访问一个节点多次,但是如果表征两次节点状态呢 ...

  9. LeetCode 821 Shortest Distance to a Character 解题报告

    题目要求 Given a string S and a character C, return an array of integers representing the shortest dista ...

随机推荐

  1. perl FileHandle 模块使用

    打开多个文件时必备啊 1 use FileHandle; 2 3 my (%index,%fh); 4 # 创建句柄,这里利用gzip 压缩下 5 foreach my $k(keys %index) ...

  2. perl 获取目录信息

    1 #!/usr/bin/perl -w 2 use strict; 3 use FindBin qw($Bin $Script); 4 5 my $rp=$Bin; 6 print "th ...

  3. 一个简单的BypassUAC编写

    什么是UAC? UAC是微软为提高系统安全而在Windows Vista中引入的新技术,它要求用户在执行可能会影响计算机运行的操作或执行更改影响其他用户的设置的操作之前,提供权限或管理员‌密码.通过在 ...

  4. 取gridview中textbox的值【C#】

    <asp:GridView ID="gridView" runat="server" OnRowCommand="gridView_RowCom ...

  5. Spark基础:(四)Spark 数据读取与保存

    1.文件格式 Spark对很多种文件格式的读取和保存方式都很简单. (1)文本文件 读取: 将一个文本文件读取为一个RDD时,输入的每一行都将成为RDD的一个元素. val input=sc.text ...

  6. 多人协作解决方案,git flow的使用

    简介 Gitflow工作流程围绕项目发布定义了严格的分支模型. 为不同的分支分配了非常明确的角色,并且定义了使用场景和用法.除了用于功能开发的分支,它还使用独立的分支进行发布前的准备.记录以及后期维护 ...

  7. eclipse上安装 windowBuilder方法

    最近因为需要用java Swing做一些组件设计,但想想以前在大学时候为了布局组件和位置设计花了很多时间.所以再网上查了一些带有可视化的设计插件用来提高工作效率. 其中一个是 windowBuilde ...

  8. 转Android Canvas和Paint基本使用

    Android Canvas和Paint基本使用   这篇文章主要介绍下画笔Paint和画布Canvas的基本使用  1.Paint 创建对象Paint mPaint = new Paint(); 常 ...

  9. Template Metaprogramming in C++

    说实话,学习C++以来,第一次听说"Metaprogramming"这个名词. Predict the output of following C++ program. 1 #in ...

  10. rust方法集

    随机数.数字对比.控制台输入 use std::io; use std::cmp::Ordering; use rand::Rng; fn main() { println!("please ...