【问题标题】:Difficulty in understanding this recursion sequence for merging K sorted Lists难以理解合并 K 个排序列表的递归序列
【发布时间】:2019-12-27 02:37:46
【问题描述】:

我一直在尝试理解这个 leetcode 问题的递归顺序,我也找到了解决方案。我了解合并函数,但我不了解发生在 mergeKLists 函数上的递归。帮助将不胜感激。请尽可能描述性地向我展示导致最终合并链表的调用和返回。 * 我了解合并功能,所以无需解释。

def mergeKLists(self, lists):
    if not lists:
        return 
    if len(lists) == 1:
        return lists[0]
    mid = len(lists)//2
    l = self.mergeKLists(lists[:mid])
    r = self.mergeKLists(lists[mid:])
    return self.merge(l, r)

def merge(self, l, r):
    dummy = cur = ListNode(0)
    while l and r:
        if l.val < r.val:
            cur.next = l
            l = l.next
        else:
            cur.next = r
            r = r.next
        cur = cur.next
    cur.next = l or r
    return dummy.next

【问题讨论】:

    标签: python recursion merge linked-list


    【解决方案1】:

    mergeKLists 成对合并列表,因此合并时它们的大小更相等,这意味着我们正在处理较小的子列表,因此我们避免了合并两个列表的不均匀 O(a+b) 时间复杂度高度不均匀的长度。递归模式类似于归并排序。

    除非有经过分析证明的性能优势,并且现实世界需要这种额外的性能,否则我会在代码审查中拒绝这一点,并告诉作者改用 for 循环。我怀疑 for 循环在实践中可能会更快,尽管他们使用的分而治之的递归在理论上更快。

    如果性能真的很重要并且我们有大量列表,那么编写一个直接合并 k 个列表的合并排序步骤会更快,方法是同步遍历所有 k 个列表并按顺序复制值,因为 O(sum(map(长度,k))) 最后一个合并步骤的时间复杂度。当然,这将取决于首先在 O(n log n) 时对每个列表进行排序的时间(如果我们使用基于比较的排序算法)。

    【讨论】:

    • 好的,谢谢你的澄清。我试图理解这种递归,因为我像在一张纸上一样一步一步地遵循它,但我不明白它是如何导致最后一个排序的合并列表的。也许是代码;也许我很笨,哈哈,但如果你有时间,你能澄清一下这些调用是如何导致最后一个链接列表的吗?就像一个简短的例子。我会很感激的
    • 在每个函数的开头添加一些调试打印,显示调用它的参数。然后用少量输入运行。
    • 好的,我会搜索如何做到这一点。这可能会回答我的问题
    猜你喜欢
    • 2019-03-20
    • 1970-01-01
    • 2019-04-07
    • 2013-10-05
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    相关资源
    最近更新 更多