[Leetcode] Maximum Subarray 子序列最大和

Maximum Subarray

最新更新请见:https://yanjia.me/zh/2019/02/…

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the largest sum = 6.

原题链接

动态规划

复杂度

时间 O(N) 空间 O(N)

思路

这是一道非常典型的动态规划题,为了求整个字符串最大的子序列和,我们将先求较小的字符串的最大子序列和。这里我们从后向前、从前向后计算都是可以的。在从前向后计算的方法中,我们将第i个元素之前最大的子序列和存入一个一维数组dp中,对第i+1个元素来说,它的值取决于dp[i],如果dp[i]是负数,那就没有必要加上它,因为这只会拖累子序列的最大和。如果是正数就加上它。最后我们再讲第i+1个元素自身加进去,就得到了第i+1个元素之前最大的子序列和。

代码

public class Solution {
    public int maxSubArray(int[] nums) {
        int[] dp = new int[nums.length];
        int max = nums[0];
        dp[0] = nums[0];
        for(int i = 1; i < nums.length; i++){
            dp[i] = dp[i-1]>0? dp[i-1] + nums[i] : nums[i];
            max = Math.max(dp[i],max);
        }
        return max;
    }
}

扫描算法

复杂度

时间 O(N) 空间 O(1)

思路

仔细观察上面的代码,我们其实只用到了dp[i-1]这个量,所以如果用一个变量记录上次的值,那么这O(N)的空间是可以省略的。我们要做的就是扫描一遍数组,遍历每个数的时候都更新这个变量。而最大子序列和的算法和上个解法还是一样的。

代码

public class Solution {
    public int maxSubArray(int[] nums) {
        int max = nums[0];
        int sum = nums[0];
        for(int i = 1; i < nums.length; i++){
            sum = sum < 0 ? nums[i] : sum + nums[i];
            max = Math.max(sum, max);
        }
        return max;
    }
}
    原文作者:ethannnli
    原文地址: https://segmentfault.com/a/1190000003481202
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞