LeetCode学习篇二——分治法

这星期学习了分治法,所以在leetcode上打算做一些相关的题,随便打开了一道相关算法题,题目如下:
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.
一开始起来,就想用最暴力最直接的方法解,于是有了以下代码:

int maxSubArray(vector<int>& nums) {
    int maxsum = nums[0];
    for (int i = 1; i <= nums.size(); i++) {
        for (int j = 0; j < nums.size()-i+1; j++) {
            int t = 0;
            for (int k = 0; k < i; k++) {
                t += nums[j+k];
            }
            if (t > maxsum) {
                maxsum = t;
                cout << maxsum << " ";
            }
        }
    }
    return maxsum;
}

测试了几个简单样例,对了~然而提交上去果然超时了,时间复杂度为O(n^3),果然要重新考虑算法。
所以想着尝试用分治法做一下~
看着这道题,完全想不出分治法怎么处理,所以翻了书里的内容再看一下,分成几部分小问题,再分,再分……
于是想着如果把数字分成两部分,最大和子序列可能在左边,也可能在右边,或者是左边和右边的一部分加起来,然后分成的两串小数组再继续按相同的方法递归下去……算法复杂度为O(Nlogn)

class Solution {
public:
    int maxSum(vector<int> & nums, int l, int r) {
        if (l == r) return nums[l];
        int mid = (l + r) / 2;
        int maxLeft = maxSum(nums, l, mid);
        int maxRight = maxSum(nums, mid + 1, r);

        int tL = 0, tR = 0;
        int maxL = INT_MIN, maxR = INT_MIN;
        for (int i = mid; i >= l; i--) {
            tL += nums[i];
            if (tL > maxL) maxL = tL;
        }
        for (int i = mid + 1; i <= r; i++) {
            tR += nums[i];
            if (tR > maxR) maxR = tR;
        }
        return maxLeft > maxRight ? (maxLeft > (maxL + maxR) ? maxLeft : (maxL + maxR)) : (maxRight > (maxL + maxR) ? maxRight : (maxL + maxR));
    }
    int maxSubArray(vector<int>& nums) {
        return maxSum(nums, 0, nums.size() - 1);
    }
};

未完待续……

你可能感兴趣的:(学习篇,leetcode)