给定一个数字数组,包括正数和负数,问题是找到一个顺序子数组,它具有最大的总和,时间复杂度为O(n),例如,[1 ,-2,3,10,-4,7,2,-5]是一个数组,子数组[3,10,-4,7,2]的最大和为18。 那么如何在O(n)中找到这个子数组呢? THX
答案 0 :(得分:2)
Wiki link到此解决方案。它被称为最大子阵列和问题。解决方案由Kadane提供,在O(n)时间运行。
答案 1 :(得分:0)
这是Python的解决方案。想法是搜索最大连续总和。如果该总和为负数,则清空列表,如果它不是负数,则必须保留这些元素。
l = [1,-2,3,10,-4,7,2,-5]
def find_max(l):
s = 0 # Current sum
lsum = [] # Current subarray
res = (0, []) # Max value and subarray
for v in l:
s += v
lsum.append(v)
if s > res[0]:
res = (s, lsum[:])
elif s < 0:
s = 0
lsum = []
return res
print find_max(l)
结果:
(18, [3, 10, -4, 7, 2])
答案 2 :(得分:0)
这个想法是看累积序列(将值视为某事物的增量/减量),然后找到该系列的低和后续高点。
在伪代码中:
sum = 0
low = Integer.MaxValue
highestSumSinceLow = Integer.MinValue
For i = 0 to Array.Length-1
sum += Array[i] // keep track of cumulative value since start
If sum < low Then
low = sum // keep track of lowest sum since start so far
substart = i + 1 // and set substart to next value
sumsincelow = sum - low // calculate sum from that low to here
If sumsincelow > highestSumSinceLow Then
highestSumSinceLow = sumsincelow // keep track of highest sumsincelow
subend = i // and set subend to this value
Next i
在遍历整个数组之后,substart
和subend
指向具有最高总和(highestSumSinceLow
)的子数组的索引。
这可能是最简单,最有效的解决方案。它是O(n)并且不使用临时数组。它从开始到结束只进行一次数组,并跟踪自开始以来的最低累积和以及自该低以来的最高总和。