连续子数组的最大和

连续子数组的最大和

在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)


这题目应该是最基础的动态规划的题目:最大子数组的和一定是由当前元素和之前最大连续子数组的和叠加在一起形成的,因此需要遍历n个元素,看看当前元素和其之前的最大连续子数组的和能够创造新的最大值。

public class Solution {
   public int FindGreatestSumOfSubArray(int[] array) {
       int len = array.length;
       int[] dp = new int[len];
       int max = array[0];
       dp[0] = array[0];
       for(int i=1; i < len; i++){
           if(dp[i-1] > 0)
               dp[i] = dp[i-1] + array[i];
           else
               dp[i] = array[i];
           if(dp[i] > max)
               max = dp[i];
       }
       return max;
   }
}

解释一下上面算法的意思,dp[i]的含义是"以第i个元素为右边界的连续子序列所能取到的最大值",它是在右边界确定的情况下、所有可能的左边界中取的最大的情况。所以dp[i]=array[i]或者array[i]+dp[i-1](dp[i-1]>0时),这是表示如果前i-1个中以第i-1为右边界时得到的最优结果如果是正的话,就将左边界作为第i个的最优左边界,否则就隔断,从本元素开始。

我们最后在所有dp[i]中选最大的,其实是在选右边界,以确定最终的连续子序列的范围。

这道题的确是动态规划,但是不是那么直接,思路需要绕个弯,但是需要掌握,了解这个思路之后就好想了


posted @ 2020-03-05 22:51  别再闹了  阅读(119)  评论(0)    收藏  举报