LeetCode 53. Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
解析:
给定一个数组,计算最大的连续子数组之和,返回最大的的和。
一维动态规划算法,在从头开始遍历的过程中,对每一个当前元素nums[i],要么在原来的基础之上加上当前元素,要么从当前元素重新开始。
定义子问题:dp[i]为以第i个元素结尾的最大连续子数组和,很显然在for循环遍历的过程中,只有两种情况:
1)dp[i]重新以当前元素nums[i]开始;
2)dp[i]继续累加,即当前元素nums[i]+dp[i-1];
对第i个元素来说,它的值取决于dp[i-1],如果dp[i-1]是负数,那就没有必要加上它,因为这只会拖累子序列的最大和。如果是正数就加上它。最后我们再将第i个元素自身加进去,就得到了第i个元素之前最大的子序列和。

另外,dp[i]表示以i元素结尾的最大数组和,即必须包括i元素,所以需要数值max_sum来记录每个阶段的结果,选择每个子问题结果中的最大值。
具体看代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int len = nums.size();
        vector<int> dp(len);
        dp[0] = nums[0];
        int max_sum = nums[0];
        for(int i=1; i< len; i++)
        { 
            int temp = dp[i-1] + nums[i];
            dp[i] = temp>nums[i]?dp[i-1] + nums[i]:nums[i];
            max_sum = max(max_sum, dp[i]);
        }
        return max_sum;
    }
};

在这里,仔细观察上面的代码,实际上只使用了dp[i-1],可以将tmp_sum数组省去,直接用一个变量递推即可,因为只和前一次结果相关。
代码更改后如下:

class Solution 
{
	public:
	int maxSubArray(vector& nums) 
	{
		int temp_sum = nums[0];
		int max_sum = nums[0];
		for (int i=1; i < nums.size(); i++) 
		{
			temp_sum = temp_sum>0?temp_sum+nums[i]:nums[i];
			max_sum = max(max_sum, temp_sum);
		}
		return max_sum;
	}
}
;

执行结果如下:

执行时间与上面的类似。

参考:
https://segmentfault.com/a/1190000003481202

One Comment

Add a Comment

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据