Maximum Subarray II

Given an array of integers, find two non-overlapping subarrays which have the largest sum.

The number in each subarray should be contiguous.

Return the largest sum.

Can you do it in time complexity O(n) ?

For given [1, 3, -1, 2, -1, 2], the two subarrays are [1, 3] and [2, -1, 2] or [1, 3, -1, 2] and [2], they both have the largest sum 7.

http://www.lintcode.com/en/problem/maximum-subarray-ii/

Discussion

利用Maximum Subarry的思想,给定任意位置,我都计算一个左右两边的max的和,这样是O(n^2) runtime, 结果提交的时候发现超时了。。。。

Solution

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer denotes the sum of max two non-overlapping subarrays
     */
    int maxTwoSubArrays(vector<int> nums) {
        // write your code here
        int n= nums.size();
        if(n == 0) return -1;
        int result = INT_MIN;
        for(int i=0; i<n-1; i++) {
            int left = maxOneSubArray(nums, 0, i);
            int right = maxOneSubArray(nums, i+1, n-1);
            if(left+right > result)
                result = left+right;
        }
        return result;

    }
private:
    int maxOneSubArray(vector<int> nums, int start, int end) {
        int result = nums[start];
        for(int i=start+1; i<=end; i++) {
            nums[i] = max(nums[i], nums[i]+nums[i-1]);
            if(nums[i] > result) {
                result = nums[i];
            }
        }
        return result;
    }
};

Follow up

计算一个从左到右的最大值,和一个从右道左的最大值。然后再选出两个不重叠的子数组和最大的情况。

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer denotes the sum of max two non-overlapping subarrays
     */
    int maxTwoSubArrays(vector<int> nums) {
        if(nums.empty()) return 0;
        int n = nums.size();
        //1. compute max sum in [0`i], save in max_left
        vector<int> max_from_left(n, INT_MIN);
        int local = 0;
        int global = INT_MIN;
        for(int i=0; i<n; i++) {
            global = max(global, local+nums[i]);
            local = max(0, local+nums[i]);
            max_from_left[i] = global;
        }
         //2. compute max sum in [i~n-1], save in max_right
        local = 0;
        global = INT_MIN;
        vector<int> max_from_right(n, INT_MIN);
        for(int i=n-1; i>=0; i--) {
            global = max(global, local+nums[i]);
            local = max(0, local+nums[i]);
            max_from_right[i] = global;
        }
        //3. find the two subarrays
        int result = INT_MIN;
        for(int i=0; i<n-1; i++) {
            result = max(result, max_from_left[i] + max_from_right[i+1]);
        }
        return result;
    }
};

results matching ""

    No results matching ""