【问题标题】:The maximum Value Contiguous Subsequence algorithm最大值连续子序列算法
【发布时间】:2017-04-27 00:26:19
【问题描述】:

这个问题的输入是一个实数数组A[1...n]。您需要找出通过将A 的连续子序列A[i],A[i+1],...A[j] 的所有数字相加可以获得的最高值是多少。如果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. 简要说明为什么您的算法确实在线性时间内运行。

【问题讨论】:

    标签: algorithm subsequence contiguous


    【解决方案1】:

    如果我们不采取任何项目(所以解决方案是一个空子数组),我们有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 }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 2023-03-07
      • 2023-03-27
      • 2021-11-09
      • 2022-12-20
      • 1970-01-01
      • 2021-10-18
      相关资源
      最近更新 更多