块不能重叠。它们也不能相邻。假设 A 的长度 > 2。
我知道这与查找最大子数组的总和非常相似,并且可以在线性时间内完成。
我也很确定该算法的开始与查找最大子数组问题相同。
这是我前几天听到的一个问题,想看看如何解决。
你可以做两次 max-subarray-algorithm 。
def max_two_sub_array():
sum = l[0] = ls[0] = 0
for i = 1 to n:
sum += a[i]
if sum < 0: sum = 0
if l[i - 1] > sum:
l[i] = l[i - 1]
ls[i] = ls[i - 1] # endpoint of l[i]
else
l[i] = sum
ls[i] = i
sum = r[n + 1] = 0
rs[n + 1] = n + 1
for i = n to 1:
sum += a[i]
if r[i + 1] > sum:
r[i] = r[i + 1]
rs[i] = rs[i + 1] # startpoint of r[i]
else
r[i] = sum
rs[i] = i
ans = 0
for i = 0 to n:
ans = max(ans, l[i] + r[i + 1])
return ans
2个步骤:
使用 O(n) 找到整个数组中最大和的块。假设块从a[i]开始,以a[j]结束,总和为S1
使用 O(n) 找到前一个块的和最小的块。假设总和为 S2
最终答案是 S1-S2
应考虑一些边界情况:
如果数组是 1,2,3,2,1。第 1 步将整个数组作为块返回。第 2 步将返回 1。但这违反了 2 个块不应相邻的要求。所以对于第 2 步,你应该应用从 a[i+1] 开始并以 a[j-1] 结束的算法