leetcode 847. 访问所有节点的最短路径 -比特位表示访问情况-双端队列和字典初始值设置-BFSvsDFS- 2log2(n) vs n

特别鸣谢:来自夸夸群的 醉笑陪公看落花@知乎王不懂不懂@知乎
感谢醉笑陪公看落花@知乎 倾囊相授,感谢小伙伴们督促学习,一起进步

相关文章:

847. 访问所有节点的最短路径

存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。

给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。

返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes
在这里插入图片描述

输入:graph = [[1,2,3],[0],[0],[0]]
输出:4
解释:一种可能的路径为 [1,0,2,0,3]

解法1 - 比特位状态+BFS+动态规划- 通过

class Solution:
    def shortestPathLength(self, graph: List[List[int]]) -> int:
        return solve1(graph)
import collections
def solve1(graph):
    N = len(graph)
    q = collections.deque([[1<<i,i] for i in range(N)])
    dist = collections.defaultdict(lambda :N*N)
    for i in range(N):dist[1<<i,i]=0
    while q:
        cover,i = q.popleft()
        d = dist[cover,i]
        if cover==2**N-1:return d
        for c in graph[i]:
            cover2 = cover | 1<<c
            if d+1<dist[cover2,c]:
                dist[cover2, c] = d+1
                q.append([cover2,c])

方法2 - 比特位状态+DFS+动态规划 - 超时

class Solution:
    def shortestPathLength(self, graph: List[List[int]]) -> int:
        return solve2(graph)
'''
比特位状态+DFS+动态规划
'''
import collections
def solve2(graph):
    N = len(graph)
    dist = collections.defaultdict(lambda :N*N)
    for i in range(N):dist[1<<i,i]=0
    for i in range(N):
        DFS(graph, dist, 1 << i, i)
    distance = [dist[2**N-1, i] for i in range(N)]
    return min(distance)
def DFS(graph,dist,cover,i):
    N = len(graph)
    if cover == 2 ** N - 1: return
    d = dist[cover, i]
    for c in graph[i]:
        cover2 = cover | 1 << c
        if d + 1 <= dist[cover2, c]:
            dist[cover2, c] = d + 1
            DFS(graph,dist,cover2, c)

小知识点

python

import collections

  • 双端队列 q = collections.deque([[1<<i,i] for i in range(N)])
  • 字典指定初始值 dist = collections.defaultdict(lambda :N*N)

比特位表示图的访问情况

1<<i 用比特位记录i节点被访问这个事情

BFS vs DFS

  • 当解空间离root较近的时候, 用BFS (相当于从多个出发点开始寻找)
  • 当解空间离root较远的时候, 用DFS (相当于从一个出发点开始找,直到找到叶子结点,再从另一个出发点开始找)

本地的解空间离root较进,用BFS比较合适. 此外, 用DFS需要把所有路径找完了,再求一遍不同出发点得到的最小值. 而BFS 只需要找到第一个遍历到所有节点的路径,就是最小值了

时间复杂度比较 2log2(n) vs n

f(n) = 2log2(n) - n 的图像如下
n在 2~4之间的时候, 2log2(n) 大于n
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值