LeetCode - Maximum Subarray

本文介绍了一种寻找具有最大和的连续子数组的算法。通过动态规划方法,可以在O(n)的时间复杂度内解决问题,并提供了分治策略实现,进一步探讨了不同情况下的解决方案。

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.

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.

http://oj.leetcode.com/problems/maximum-subarray/


Solution:

Still simple dp. Add the element from the start. If sum > max, update sum, if sum < 0, reset sum to 0.

And for the divide and conquer solution, obviously we need to use binary partition. The result would only be 3 conditions:

1, in left half; 2, in right half; 3, cross the middle

For 1st and 2nd condition, we can use recursion. For 3rd condition, we can scan the array from middle and find the maximum sub array in left half and right half.

https://github.com/starcroce/leetcode/blob/master/maximum_subarray.cpp

class Solution {
public:
    int maxSubArray(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int max = -10000;
        int current = 0;
        for(int i = 0; i < n; i++){
            current += A[i];
            if(current > max){
                max = current;
            }
            if(current < 0){
                current = 0;
            }
        }
        return max;
    }
};
// 68 ms for 200 test cases
// divide and conquer solution, O(nlogn)
class Solution {
public:
    int maxSubArray(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int totalMax = INT_MIN;
        return maxSubArray(A, 0, n-1, totalMax);
    }
    
    int maxSubArray(int A[], int start, int end, int &totalMax) {
        if(start > end) {
            return INT_MIN;
        }
        int middle = (start + end) / 2;
        // recursive to left half and right half
        int leftMax = maxSubArray(A, start, middle-1, totalMax);
        int rightMax = maxSubArray(A, middle+1, end, totalMax);
        // update the max
        totalMax = max(max(totalMax, rightMax), leftMax);
        // start from middle, find the maximum subarray in left and right
        int sum = 0, curLeftMax = 0, curRightMax = 0;
        for(int i = middle-1; i >= start; i--) {
            sum += A[i];
            if(sum > curLeftMax) {
                curLeftMax = sum;
            }
        }
        sum = 0;
        for(int i = middle+1; i <= end; i++) {
            sum += A[i];
            if(sum > curRightMax) {
                curRightMax = sum;
            }
        }
        // update the max
        totalMax = max(totalMax, curLeftMax + A[middle] + curRightMax);
        return totalMax;
    }
};



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值