leetcode-Maximum Subarray

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.

click to show more practice.

More practice:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.


一种动态规划的例子。和分治法相同,当问题规模比较大不容易解决时,我们试图减小问题规模来解决这些问题。分治法将一个大问题分解成几个规模小的小问题,每个小问题的解相互独立,然后将这些小问题的解合并成原问题的解。由于小问题和原问题的性质相同,可以用递归法

这里用分治法反而比较麻烦。可以用数学归纳法的思想将问题规模为n的问题化为问题规模为n-1 的问题然后推导规模增加了一之后问题的解有什么变化(即求其递推公式)。

数组元素增加一之后最大的subArray sum 有可能有两种情况。第一不变,第二有变化,那肯定新添加进的元素包含在subArray中,那我们就保存两个量一个是最大的subArray sum 一个是以最后一个元素为结尾的子列的最大subArray sum值。即后面的max 和maxend

加进一个新元素之后先更新一下maxend,更新方法是看一下前面的maxend是否大于0,如果大于0加上去,如果小于0的话加上去反而更小。然后就可以比较一下新的maxend 和之前的max哪个大,更新一下max就行。。

class Solution {
public:
    int maxSubArray(int A[], int n) {
        int max=A[0];
        int maxend=A[0];
        for(int i=1;i<n;i++)
        {
            if(A[i]+maxend<A[i])maxend=A[i];
            else maxend=A[i]+maxend;
            if(maxend>max)max=maxend;
         
            
        }
        return max;
    }
    
};

还有其他的方法,为了保持完整性也贴在下面,以下为转载(repost)

原链接


greedy:

class Solution {
public:
    int maxSubArray(int A[], int n) {
        int sum = 0, min = 0, res = A[0];
        for(int i = 0; i < n; i++) {
            sum += A[i];
            if(sum - min > res) res = sum - min;
            if(sum < min) min = sum;
        }
        return res;
    }
};

The idea is to find the largest difference between the sums when you summing up the array from left to right. The largest difference corresponds to the sub-array with largest sum. I worked it out independently although It is very close to lucastan's solution https://oj.leetcode.com/discuss/11288/simple-o-n-c-solution-no-dp-no-divide-and-conquer

divide and conquer:

struct val {
    int l, m, r, s;
    val(int l, int m, int r, int s):l(l), m(m), r(r), s(s){}
};

class Solution {
public:
    val dac(int A[], int n) {
        if(n == 1) return val(A[0], A[0], A[0], A[0]);
        val v1 = dac(A, n / 2), v2 = dac(A + n / 2, n - n / 2);
        int l, m, r, s;
        l = max(v1.l, v1.s + v2.l);
        m = max(v1.r + v2.l, max(v1.m, v2.m));
        r = max(v2.r, v1.r + v2.s);
        s = v1.s + v2.s;
        return val(l, m, r, s);
    }
    int maxSubArray(int A[], int n) {
        val v = dac(A, n);
        return v.m;
    }
};

the idea is: for each sub array we calculate 4 values in O(1) time based on the return values of its two halves. The meaning of the values:

  • l: the sum of the sub array with largest sum starting from the first element
  • m: the sum of the sub array with largest sum
  • r: the sum of the sub array with largest sum ending at the last element
  • s: the sum of the whole array

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值