【三次过】Lintcode 42. 最大子数组 II

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/81735492

给定一个整数数组,找出两个 不重叠 子数组使得它们的和最大。
每个子数组的数字在数组中的位置应该是连续的。
返回最大的和。

样例

给出数组 [1, 3, -1, 2, -1, 2]
这两个子数组分别为 [1, 3] 和 [2, -1, 2] 或者 [1, 3, -1, 2] 和 [2],它们的最大和都是 7

挑战

要求时间复杂度为 O(n)

注意事项

子数组最少包含一个数


解题思路1:

既然在上一题Lintcode 41:Maximum Subarray已经可以求出整个数组的最大和子数组,那么这个题目就是增加了一条分界线,求分界线左右两边的子数组的最大和相加,很容易想到:遍历分界线,依次求取分界线两端的最大和。这样做的时间复杂度为O(n^2),代码如下:

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 res = INT_MIN;
        
        for(int i=0 ; i+1 < nums.size() ; i++)
        {
            int max1 = maxSubArrays(nums , 0 , i);//求nums[0..i]的最大子数组和
            int max2 = maxSubArrays(nums , i+1 , nums.size()-1);//求nums[i+1...nums.size()-1]的最大子数组和
            
            int temp = max1 + max2;
            
            res = res > temp ? res : temp;
        }
        
        return res;
    }
    
    //求nums[l...r]之间最大子数组和
    int maxSubArrays(vector<int> & nums , int l , int r)
    {
        int max = nums[l];
        int temp = 0;
        
        for(int i = l ; i <= r ; i++)
        {
            temp += nums[i];
            
            max = max > temp ? max : temp;
            
            if(temp < 0)
                temp = 0;
        }
        
        return max;
        
    }
};

解题思路2:

同样是上面的思路,但是利用空间换时间的方式,先从左向右遍历,将左边子数组所有最大和保存在一个数组中,再从右向左遍历,将右边子数组所有最大和保存在另一个数组中,最后将两个数组彼此不相交的位置进行相加即可。这样做的时间复杂度为O(n).

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
        vector<int> lRes(nums.size() , INT_MIN);
        lRes[0] = nums[0];
        int temp = nums[0];
        
        for(int i=1 ; i < nums.size() ; i++)
        {
            temp = max(temp+nums[i] , nums[i]);
            lRes[i] = max(temp , lRes[i-1]);
        }
        
        vector<int> rRes(nums.size() , INT_MIN);
        rRes[nums.size()-1] = nums[nums.size()-1];
        temp = nums[nums.size()-1];
        
        for(int i=nums.size()-2 ; i >=0 ;i--)
        {
            temp = max(temp+nums[i] , nums[i]);
            rRes[i] = max(temp , rRes[i-1]);
        }
        
        int res = INT_MIN;
        for(int i=0 ; i+1 < nums.size() ; i++)
        {
            int t = lRes[i] + rRes[i+1];
            
            res = res > t ? res : t;
        }
        
        return res;
    }
    
};

猜你喜欢

转载自blog.csdn.net/majichen95/article/details/81735492
42.
今日推荐