【问题标题】:Generative recursion to find the sublist with the maximum sum生成递归以找到总和最大的子列表
【发布时间】:2014-06-13 13:53:46
【问题描述】:

我正在尝试解决 Python 中的生成递归问题。问题是:

  • 在由整数组成的列表中,找到相邻的子列表 最大的总和并返回该总和。
  • 例如,如果给定的列表是 [-2, 1, -3, 4, -1, 2, 1, -5, 4],则具有最大和的相邻子列表是 [4, -1, 2, 1],总和为 6

我必须按照给定的算法来求解 find_max:

  1. 将给定列表(在中点)拆分为两部分:L_left 和 L_right。
  2. 返回以下 3 的最大值:
    • 任何子列表的最大总和完全位于 L_left 中(使用对 find_max 的递归调用)。
    • 任何子列表的最大总和完全位于 L_right 中(使用对 find_max 的递归调用)。
    • 重叠L_left和L_right的最大子列表; IE。,
      • 首先:查找从中点(向左)开始到某个点结束的任何子列表的最大总和 在中点的左侧
      • 第二个:找到从中点开始的任何子列表的最大总和(朝向 右)并在中点右侧的某个点结束
      • 最后:将两个最大值相加。

我尝试了以下方法:

def find_max(L):
    length = len(L)
    mid_index = length/2
    if length == 1:
        return L[0]
    else:
        left = find_max(L[0:(length/2)])
        right = find_max(L[(length/2):length])
        max_subset = max(left,right,left+right)
        return max_subset

这能够解决长度为 2 的列表。如何扩展它以适用于具有更多元素的列表?

【问题讨论】:

  • 你能定义“相邻子列表”吗,因为我不明白[1, 2, -1, 4][−5, 1, 4, −2, 2, −1, 2, −3, 1, −3, 4] 的相邻子列表。据我了解,具有最大值的相邻子列表将是 [1, 4, -2, 2, -1, 2],总和为 6。
  • [1, 2, -1, 4] 不是[−5, 1, 4, −2, 2, −1, 2, −3, 1, −3, 4] 的子列表。有错别字吗?
  • 使用递归时的一个提示:@memoize 装饰器有助于提高递归速度,因为递归通常是一个坏主意,由于时间消耗 - 如果您对此感兴趣:wiki.python.org/moin/PythonDecoratorLibrary#Memoize我知道这不是你问题的真正答案,尽管这是一个重要的评论
  • @memoize 不会改变算法。
  • 如果您有能力使用分而治之的解决方案,我真诚地建议您这样做:stackoverflow.com/questions/15062844/maximum-sum-sublist

标签: python algorithm recursion sublist


【解决方案1】:

你没有考虑以下:

  • 另一个基本情况:L 是 []
  • 左半边和右半边应该是连续的。
    • 根据您的代码,如果L[2, -5, 3],在第一次递归中,left + right 将产生 5。

def find_max(L):
    length = len(L)
    mid_index = length/2
    if length == 0:
        return 0
    elif length == 1:
        return max(L[0], 0)

    left = find_max(L[:mid_index])
    right = find_max(L[mid_index:])

    left_half = right_half = 0
    # to the left
    accum = 0
    for x in L[mid_index-1::-1]:
        accum += x
        left_half = max(left_half, accum)

    # to the right
    accum = 0
    for x in L[mid_index:]:
        accum += x
        right_half = max(right_half, accum)

    return max(left, right, left_half + right_half)


assert find_max([]) == 0
assert find_max([-1]) == 0
assert find_max([1, 2, 3]) == 6
assert find_max([2, -5, 3]) == 3
assert find_max([-5, 1, 4, -2, 2, -1, 2, -3, 1, -3, 4]) == 6

没有for循环:

def sum_max(L, accum=0, max_value=0):
    if not L:
        return max_value
    accum += L[0]
    return sum_max(L[1:], accum, max(max_value, accum))

def find_max(L):
    ...
    left_half = sum_max(L[mid_index-1::-1])
    right_half = sum_max(L[mid_index:])
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2015-05-03
    • 1970-01-01
    • 2018-03-18
    • 2019-04-22
    相关资源
    最近更新 更多