如何找到一个在O(n)内具有最大总和的顺序子数组

时间:2013-07-17 11:14:36

标签: algorithm data-structures time-complexity

给定一个数字数组,包括正数和负数,问题是找到一个顺序子数组,它具有最大的总和,时间复杂度为O(n),例如,[1 ,-2,3,10,-4,7,2,-5]是一个数组,子数组[3,10,-4,7,2]的最大和为18。 那么如何在O(n)中找到这个子数组呢? THX

3 个答案:

答案 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

在遍历整个数组之后,substartsubend指向具有最高总和(highestSumSinceLow)的子数组的索引。

这可能是最简单,最有效的解决方案。它是O(n)并且不使用临时数组。它从开始到结束只进行一次数组,并跟踪自开始以来的最低累积和以及自该低以来的最高总和。