Leetcode-53-Maximum Subarray

原题传送门-https://leetcode.com/problems/maximum-subarray/#/description

开始的时候还不是很理解动态规划的思路,思维的着力点用反了,网上学习理解以后做一个记录和整理。

首先分析问题,考虑到问题的规模是n,而最先考虑到的思路就是缩小问题的规模,由i的状态去推i+1的状态,因此锁定用动态规划的想法去解决问题。那么先来用个小规模的情况看看问题是怎么一步步变复杂的。我们假设有这样一个array-【-2,1,-3,4,-1,2,1,-5,4】,假设前i个数的maximum subarray的最大和为d(i)= j,那么:

d(1)=-2;

d(2)=-1;

d(3)=d(2)=-1(-3<0);

d(4)=?

到d(4)这步为止发现不对了,没有办法用一个相对直观简单的思路去递推出d(4)和前面三个d(i)的关系。到这里位置是我思维的第一阶段,大家应该可以看出来,我考虑的方式是以现有的i状态为基础,考虑第i+1个数的正负是否对最大和有贡献,但卡在这里思考良久,发现自己考虑的方向错了。然后调整思路,换个角度,我们以第i+1个数为基础,考虑前i个数中的最大和是否对我们所要求的最终结论有贡献,角度一换,思路一下子就清晰了,在这里,我们维护两个状态,其一是我们的最终所求maxSum,其二是我们所需要使用的暂时和t_sum。

在已知前i个数的最大子序列和maxSum和暂时t_sum的情况下(此时maxSum==t_sum),若加入了第i+1个元素,由于连续的限制,若t_sum<0,那么其对于增大这i+1个数的子序列的最大和没有贡献,需要将其置0。同样看刚刚的例子:

maxSum(1) = -2,t_sum(1)=-2;

因为t_sum<0,因此置t_sum = 0,maxSum(2) = 1;t_sum(2) = 1;

因为t_sum>0,但-3<0,因此maxSum(3) = maxSum(2)= t_sum(2) =1;

...以此类推。

Talk is cheap,show me the code:

public class Solution {
    public int maxSubArray(int[] nums) {
        if(nums==null||nums.length==0)//判断数组为空
           return 0;
        int maxSum = nums[0];
        int t_sum = nums[0];
        for(int i = 1;i<nums.length;i++){
           t_sum = Math.max(nums[i],t_sum+nums[i]);
           maxSum = Math.max(t_sum,maxSum);
        }
        return maxSum;
    }
}
以上代码参考学习了前辈大神的代码,侵删。从代码里,应该很容易地感受到动态规划的思想了,从i到i+1的递推十分明显。这时候我们的算法的复杂度已经是O(n)了。下面同样给出一个算法复杂度为线性时间的算法,不详细展开了,给出传送门: http://blog.csdn.net/joylnwang/article/details/6859677

希望大家能从这个简单的算法中有所收获。

猜你喜欢

转载自blog.csdn.net/cambridgewoo/article/details/70573576