【问题标题】:Why is graph DFS faster with LRU Cache than Dictionary lookup. LeetCode 128 solution difference为什么使用 LRU 缓存的图形 DFS 比字典查找更快。 LeetCode 128 解法区别
【发布时间】:2021-11-29 23:07:10
【问题描述】:

我在做 leetcode 128(最长的连续序列)。这就是问题: problem picture

我编写了 2 个可行的解决方案,均使用 DFS。

第一种方案使用lrucache缓存DFS函数

第二个解决方案使用字典来做同样的事情(我认为)。

解决方案 1 明显更快(~500ms vs ~4000ms),但我真的不明白为什么。据我了解,它们本质上是在做同样的事情。我错过了什么?

这里有两种解决方案:

解决方案 1(LRU 缓存)(更快):

def longestConsecutive(self, nums: List[int]) -> int:
    
    graph = dict()
    for num in nums:
        graph[num] = num+1
    
    @functools.lru_cache(maxsize = None)
    def dfs(num):
        if num in graph:
            return 1 + dfs(graph[num])
        return 0
    
    longest = 0
    for num in nums:
        longest = max(longest, dfs(num))
            
    return longest

解决方案 2(字典查找)(较慢):

def longestConsecutive(self, nums: List[int]) -> int:
    
    graph = dict()
    for num in nums:
        graph[num] = num+1
    
    def dfs(num):
        if num in graph:
            return 1 + dfs(graph[num])
        return 0
    
    longest = 0
    for num in nums:
        if num-1 not in graph:
            longest = max(longest, dfs(num))
            
    return longest

【问题讨论】:

  • 请在这里分享代码。
  • @memoricab 抱歉,现在完成
  • @memoricab 我在该帖子上看到 1 条评论,其中提到 lru_cache_wrapper() 是用 C 实现的,这使得它比 Python 字典更快。我在网上找不到任何进一步的信息来证实/提供有关此评论的更多详细信息。您是否碰巧对此了解更多?

标签: python dictionary caching graph depth-first-search


【解决方案1】:

当所有数字都是唯一的时,代码“做同样的事情”。使用缓存或唯一性过滤,运行时保证是线性的,但目前是二次的。

这个问题是在有向图中找到路径的最大长度,其中该图由不相交的路径联合组成。 DFS 只是跟随边缘直到它到达一个接收器。

第一个版本使用缓存保证每条路径只走一次;第二个版本试图通过仅在我们位于路径的起点时调用 DFS 来保证每条路径只走一次。

考虑以下输入:

nums = [1,2, ..., n] + [0]*n

然后我们为每个0 走一遍长度为n 的完整路径,所以n 总共走。您可以通过添加 5 个字符来删除重复项,将第二个版本修复为 O(n)

    for num in set(nums):
        if num-1 not in graph:
            longest = max(longest, dfs(num))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2018-10-03
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    相关资源
    最近更新 更多