最大值连续子序列算法

时间:2016-12-12 07:11:15

标签: algorithm subsequence contiguous

此问题的输入是实数的数组A[1...n]。您需要通过总结A[i],A[i+1],...A[j]的{​​{1}}的所有连续子序列A来找出可以获得最高值的内容。如果A不包含负数,则问题很简单,可以通过总结A的所有元素来解决。当A包含正数和负数的混合时,它变得更加棘手。

例如,对于A = [-2,11,-4,13,-5,-3],解决方案是20 (11-4 + 13 = 20)。对于A = [-2,1,-3,4,-1,2,1,-5,4],解决方案为6 (4-1 + 2 + 1 = 6)。空子序列的总和为0

有一种强力解决方案可以解决 O(n ^ 3) 中的这个问题,但也可以在线性时间内解决问题。

  1. 设计一种在线性时间内解决上述问题的算法。用伪代码展示你的算法。
  2. 简要说明算法的工作原理和原因。
  3. 简要说明您的算法确实在线性时间内运行的原因。

1 个答案:

答案 0 :(得分:0)

如果我们不接受任何项目(因此解决方案是空子阵列),我们将0作为解决方案。 这就是规则的原因:

 When running `sum` drops to `0` or below, restart summing. 

有点棘手的时刻是总结我们遇到一个负数:

 3, 4, 5, -1 ...

我们可以离开它(并3 + 4 + 5 == 12}或接受它希望会出现正数 很快:

3, 4, 5, -1, 100, 200, 300

要解决这种歧义,我们可以记住最好sumresult并继续求和。 C#实现:

private static double Solution(IEnumerable<double> source) {
  // We can guarantee 0 (for empty subarray) 
  double result = 0;
  double sum = 0; 

  // Linear: all we have to do is to scan the collection 
  foreach (var item in source) 
    if (sum + item <= 0) // when sum drops to zero
      sum = 0;           // ... restart summing
    else {
      sum += item;

      if (sum > result)  // update the best sum so far on each decision
        result = sum;
    }

  return result;
}

试验:

// 6
Console.WriteLine(Solution(new double[] { -2, 1, -3, 4, -1, 2, 1, -5, 4 }));
// 20
Console.WriteLine(Solution(new double[] { -2, 11, -4, 13, -5, -3 }));