leetcode 1786 dijkstra + 记忆化搜索

23 篇文章 0 订阅
6 篇文章 0 订阅
这篇博客介绍了一道结合了Dijkstra算法和记忆化搜索的LeetCode题目。首先利用Dijkstra计算单源最短路径,随后通过记忆化搜索优化深度优先搜索,将每个状态的解决方案存储在dp数组中,实现状态复用,提高效率。作者还提到,记忆化搜索可以简化为一行代码,展示了其简洁性和强大功能。
摘要由CSDN通过智能技术生成

这题还是有点意思的,算是个杂交题。先用dijkstra求出题目要求的单源最短路径,再用记忆化搜索优化dfs。这里dfs是可以用记忆化搜索优化的,将dfs的每一个状态含有的解计算好后放入dp数组,这样下次再遇到这个状态就可以直接返回。

from heapq import *
from collections import defaultdict
class Solution(object):
    def countRestrictedPaths(self, n, edges):
        """
        :type n: int
        :type edges: List[List[int]]
        :rtype: int
        """
        class Node:
            def __init__(self, node, dist):
                self.node = node
                self.dist = dist
            
            def __lt__(self, n):
                return self.dist < n.dist

        MAX = 1 << 31
        MOD = int(1e9 + 7)
        
        # 处理边
        node2edges = defaultdict(list)
        for edge in edges:
            node2edges[edge[0]].append((edge[1], edge[2]))
            node2edges[edge[1]].append((edge[0], edge[2]))
        
        # 求单源最短路
        dis = [MAX for _ in range(n+1)]
        dis[n] = 0
        o = set([i for i in range(1, n)])

        min_node = n
        minheap = [Node(i, dis[i]) for i in range(1, n)]
        heapify(minheap)
        while len(o) > 0:
            # 更新选中节点的邻接节点
            for node, dist in node2edges[min_node]:
                dist += dis[min_node]
                if dist < dis[node]:
                    dis[node] = dist
                    heappush(minheap, Node(node, dist))
            
            # 选择距离最小节点
            while True:
                n0 = heappop(minheap)
                min_node, dist = n0.node, n0.dist
                if min_node in o: break
                    
            o.remove(min_node)
        
        dp = [0 for _ in range(n+1)]
        def dfs(node):
            if node == n:
                return 1

            if dp[node] > 0: return dp[node]
            ret = 0
            edges = node2edges[node]
            for new_node, dist in edges:
                if dis[node] > dis[new_node]:
                        ret += dfs(new_node)%MOD

            dp[node] = ret%MOD
            return ret%MOD

        ret = dfs(1)%MOD
        return ret

经过新的题发现,记忆化搜索只需一行代码。真牛啊。

	@cache
	def dfs(node):
	    if node == n:
	        return 1
	
	    ret = 0
	    edges = node2edges[node]
	    for new_node, dist in edges:
	        if dis[node] > dis[new_node]:
	                ret += dfs(new_node)%MOD
	
	    return ret%MOD
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值