leetcode

来源:互联网 发布:瑞士莲 费列罗 知乎 编辑:程序博客网 时间:2024/06/03 12:42

53. Maximum Subarray

Find the contiguoussubarray within an array (containing at least one number) which has the largestsum.

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

 

 

求最大连续子序列的和。

 

DP的经典问题,这里就粗略讲一下。

 

算法思想

对于动态规划的问题,一般有两种解法:自顶向下或者自底向上。在这个问题中,采用了自底向上的方法。利用一个数组d来记录当前序列长度的最大字段和。比如d[i]就代表着第前i个元素的最大字段和,sum代表当前子序列的和(不理解sum请看下面具体实现)。假设d[i]等于x,那么x是有两种情况的,大于等于0 or 小于0。那d[i+1]就可以利用d[i]和当前的和来求得了(递归求解子问题)。

步骤

1.  初始化d[0]的值,和sum的值,sum =nums[0] ,d[0] = nums[0]。

2.  从元素下标为i=1开始遍历数组nums,每遍历到一个元素就更新sum的值,在这里sum值有两种情况:

a)        大于等于0 :因为sum大于等于0,就取d[i] = max(d[i-1],sum)。(举个例子,2,-1,3,那么d[1] 就等于 max(2,2-1),这样就可以记录下前两个元素的最大字段和为2,但sum此时等于1,然后d[3] = max(d[2],1+3),然后一直循环下去就可以得到解,若想要构造最优解,可以再建立一个数组保存下标志)

b)        小于0 :因为sum小于0,一个数字加上一个小于0的数字比如小于这个数字。所以我们需要更新sum的值,使之为0,因为0是加法符号的单位元。

3.  最后,返回d[n-1]。


class Solution {public:    int maxSubArray(vector<int>& nums) {        if(nums.size() < 1)return 0;        if(nums.size() == 1) return nums[0];        int n = nums.size();        int *d = new int[n];        int sum = max(0,nums[0]);        d[0] = nums[0];        for(int i = 1 ; i < n ; i++){            sum += nums[i];            d[i] = max(d[i-1] , sum);            if (sum < 0){                sum = 0;            }//if sum > 0        }//for(i)        return d[n-1];    }};


 

0 0
原创粉丝点击