【Leet Code】53. Maximum Subarray---Medium

来源:互联网 发布:有淘宝号怎么开店 编辑:程序博客网 时间:2024/06/05 18:29

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.

思路一:

遍历数组元素,每次加一个新的元素,如果当前和sum>之前保存的结果result,令result=sum;如果sum<0,令sum=0.最后result保存的就是最大的和值。

思路二:

就是实现题目中说到的divide and conquer approach。

1)将数组从mid分成left、right两部分,迭代找到leftMax和rightMax。令subMax=max(leftMax,rightMax)

2)然后是找mid连接的左右两边的元素的最大值。

先找mid左边的和最大值leftContigousMax(一定要包含nums[mid],不然不是连续的和了),如果leftContigousMax就可以直接返回subMax了(因为这时可以肯定右边的最大值rightMax是最大的)。

同理,找到mid右边的和最大值rightContigousMax,如果rightContigousMax<0,直接返回subMax;

否则返回max(subMax,leftContigousMax+rightContigousMax)。

代码实现一:

class Solution {public:    int maxSubArray(vector<int>& nums) {        if(nums.size() < 1) return 0;        int result = INT_MIN;        int sum = 0;                for(auto num: nums)        {            sum += num;            if(sum > result) result = sum;            if(sum < 0) sum = 0;        }                return result;            }};

代码2实现:
class Solution {public:    int maxSubArray(vector<int>& nums) {        return maxSubArrayRec(nums, 0, nums.size() -1);    }private:int maxSubArrayRec(vector<int>&nums, int i, int j) {    if(i==j)        return nums[i];    int mid = (i + j) / 2;    int leftMax = maxSubArrayRec(nums,i,mid);    int rightMax = maxSubArrayRec(nums,mid+1,j);    int subMax = max(leftMax,rightMax);    int leftContiguousMax = nums[mid];    int leftSum = nums[mid];    for(int k=mid-1; k>=i; k--) {        leftSum += nums[k];        if(leftSum > leftContiguousMax)            leftContiguousMax = leftSum;    }    if(leftContiguousMax <= 0)        return subMax;    int rightContigousMax = nums[mid+1];    int rightSum = nums[mid+1];    for(int k=mid+2; k<=j; k++) {        rightSum += nums[k];        if(rightSum > rightContigousMax)            rightContigousMax = rightSum;    }    if(rightContigousMax <= 0)        return subMax;    return max(subMax,leftContiguousMax+rightContigousMax);}};


0 0