Генеративная рекурсия для поиска подсписка с максимальной суммой
Я пытаюсь решить проблему генеративной рекурсии в Python. Вопрос:
- в списке, состоящем из целых чисел, найдите смежный подлист, который имеет самая большая сумма и верните эту сумму.
- например, если данный список [-2, 1, -3, 4, -1, 2, 1, -5, 4], смежный подсписок, который имеет наибольшую сумму [4, -1, 2, 1], который имеет сумму 6
Я должен следовать заданному алгоритму для решения find_max:
- разделить данный список (в середине) на два: L_left и L_right.
- возвращает максимальное значение следующего 3:
- максимальная сумма любого подсписка полностью находится в L_left (используя рекурсивный вызов find_max).
- максимальная сумма любого подсписка полностью находится в L_right (используя рекурсивный вызов find_max).
- максимальный подлист, который перекрывает L_left и L_right; т. е.,
- во-первых: найти max сумма любого подсписка, начинающегося с середины (влево) и заканчивающегося в какой - то точке слева от середины!--5-->
- Second: найти максимальную сумму любого подсписка, начиная с середины (в направлении справа) и заканчивается в какой-то точке справа от середины
- наконец: добавьте две максимальные суммы.
я попробовал следующее:
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 ответов
вы не подумали о следующем:
- другой базовый случай: 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:])
...