【问题标题】:Translating recursion to divide and conquer将递归转化为分而治之
【发布时间】:2021-03-14 23:59:57
【问题描述】:

我正在尝试返回列表中最小的三个项目。下面是我写的一个 O(n) 的解决方案:

def three_smallest(L):
    # base case
    if (len(L) == 3):
        return sorted(L)
        
    current = L[0]
    (first_smallest,second_smallest,third_smallest) = three_smallest(L[1:])
    
    if (current < first_smallest):
        return (current, first_smallest, second_smallest)
    elif (current < second_smallest):
        return (first_smallest, current, second_smallest)
    elif (current < third_smallest):
        return (first_smallest, second_smallest, current)
    else:
        return (first_smallest,second_smallest,third_smallest)

现在我正在尝试编写一种分而治之的方法,但我不确定应该如何划分列表。任何帮助将不胜感激。

请注意,这个解决方案(据我所知)不是分而治之。这只是一个基本的递归解决方案,因为分而治之涉及将长度为 n 的列表除以整数 b,并在这些部分上调用算法。

【问题讨论】:

    标签: recursion divide-and-conquer


    【解决方案1】:

    对于分而治之,您通常希望将一组(大致)分成两半,而不是一个一个地削减它。也许以下内容可以满足您的需求?

    def three_smallest(L):
        if (len(L) <= 3):    # base case, technically up to 3 (can be fewer)
            return sorted(L)        
        mid = len(L) // 2    # find the midpoint of L
        # find (up to) the 3 smallest in first half, ditto for the second half, pool
        # them to a list with no more than 6 items, sort, and return the 3 smallest
        return sorted(three_smallest(L[:mid]) + three_smallest(L[mid:]))[:3]
    

    请注意,由于基本情况的不等式,此实现没有最小列表大小要求。

    在规模的另一端,您的原始实现仅限于包含少于一千个值的列表,否则它将破坏递归堆栈。上面给出的实现能够毫无问题地处理一百万个值的列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-12
      • 2012-02-25
      • 1970-01-01
      • 2020-01-19
      • 2020-09-21
      • 2020-04-11
      • 2016-05-01
      • 2017-07-16
      相关资源
      最近更新 更多