【转载】LeetCode-53:Maximum Subarray (和最大的连续子数组)

转自 https://blog.csdn.net/Koala_Tree/article/details/78367481

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

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.
1
2
问题解析:

在给定数组中找到和最大的连续子数组,子数组至少包含一个元素。

Answer
Solution 1:
DP解决。

首先以本题的例子解释一下:已知数组的前k个元素的和最大子的序列的和为maxSub(每次均比较记录),以及前k个数组的临时和sum。如果添加了第k+1个元素,由于题目中说明是连续子序列这个限制,所以如果k+1这个元素之前的和,也就是sum是小于0的,那么前面的和对于增加的k+1这个元素从而去组成最大子序列是没有贡献的,所以可以直接将sum置0。
如题目中的数组:[-2,1,-3,4,-1,2,1,-5,4],就以前两个元素[-2,1]为例,sum = -2 < 0 ,对于数字1来说,加前面的数组-2只会减小它,所以直接置sum=0,新的sum=0+1=1;对[-2,1,-3,4]来说,子数组[-2,1,-3]经过计算后的临时sum = -2 < 0,对于数字4来说,前面的和只会减小它,所以直接置sum=0,新的sum=0+4=4;
注意,只要sum不减到负数,中间出现小于0的元素是没关系的,sum仍然可以继续累加。
算法:利用动态规划思想,已知0,..,k的最大和以后,0,…k+1的最大和为:
1)若sum[k]>=0,sum[k+1]=sum[k]+A[k+1];
2)若sum[k]<0,sum[k+1]=A[k+1]。
 

class Solution {
    public int maxSubArray(int[] nums) {
        int maxSoFar = nums[0], maxEndingHere = nums[0];
        for (int i = 1; i < nums.length; ++i){
            maxEndingHere = Math.max(maxEndingHere+nums[i], nums[i]);
            maxSoFar = Math.max(maxSoFar, maxEndingHere);   
        }
        return maxSoFar;
    }
}


时间复杂度:O(n),空间复杂度:O(1)

public int maxSubArray(int[] A) {
        int n = A.length;
        int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];
        dp[0] = A[0];
        int max = dp[0];

        for(int i = 1; i < n; i++){
            dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);
            max = Math.max(max, dp[i]);
        }

        return max;
}


时间复杂度:O(n),空间复杂度:O(n)
Solution 2:
贪心算法。

下面的思想其实和DP是相似的。其从头开始一直保持将数组加入进来,直到sum < 0,则将sum置为0,ans一直保存最大的和。

/*
Idea is very simple. Basically, keep adding each integer to the sequence until the sum drops below 0. If sum is negative, then should reset the sequence.
*/
class Solution {
    public int maxSubArray(int A[], int n) {
        int ans=A[0],i,j,sum=0;
        for(i=0;i<n;i++){
            sum+=A[i];
            ans=max(sum,ans);
            sum=max(sum,0);
        }
        return ans;
    }
}


时间复杂度:O(n),空间复杂度:O(1)
————————————————
版权声明:本文为CSDN博主「大树先生的博客」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Koala_Tree/article/details/78367481

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值