leetcode 52:Maximum Subarray

来源:互联网 发布:女神联盟2进阶12数据 编辑:程序博客网 时间:2024/05/16 18:13

题目:

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.

思路:

首先想到的是用动态规划来做,因为动态规划跟前面计算的结果有关。

所以,对于给定的数组nums,我们可以定义一个相同大小的数组DP来存储当前元素对应的最大的连续元素之和。

[−2,1,−3,4,−1,2,1,−5,4]举例分析。

当i=0时,DP[i]=-2;

当i=1时,DP[i]=1;

当i=2时,DP[i]=-2;

当i=3时,DP[i]=4;

......

很容易得出DP的递推式如下:

DP[i]=max(DP[i-1]+nums[i],nums[i]);

DP中最大值即为最后的返回值。

时间复杂度:O(n);


实现如下:

class Solution {public:int maxSubArray(vector<int>& nums) {int size = nums.size();int maxSum = nums[0];vector<int> DP(size, 0);DP[0] = nums[0];for (int i = 1; i < size; i++){DP[i] = max(DP[i - 1] + nums[i], nums[i]);if (DP[i]>maxSum) maxSum = DP[i];}return maxSum;}};

下面针对more practice,用分而治之的方法求解(参考:算法导论):

分治策略是将数组分成两个规模尽可能相等的子数组,然后求解两个子数组。

但是最大子数组有可能出现在以下几种情况中:

完全位于子数组nums[low...mid]中;

完全位于子数组nums[mid...high]中;

跨越了中点;

因此我们需在上面三种情况中找最大者。

时间复杂度:O(nlgn)

实现如下:

class Solution {public:int maxSubArray(vector<int>& nums) {int size = nums.size();if (size == 1) return nums[0];return FindMaximumSubArray(nums,0,size-1);}private:int FindMaxCrossingSubArray(vector<int>& nums, int low, int mid, int high){int leftSum = -0XFFFF, rightSum = -0XFFFF, tempSum = 0;for (int i = mid; i >= low; i--){tempSum += nums[i];if (tempSum > leftSum) leftSum = tempSum;}tempSum = 0;for (int i = mid + 1; i <= high; i++){tempSum += nums[i];if (tempSum > rightSum) rightSum = tempSum;}return leftSum + rightSum;}int FindMaximumSubArray(vector<int>& nums, int low, int high){if (high == low) return nums[low];int mid = (low + high) / 2;int leftSum = FindMaximumSubArray(nums,low,mid);int rightSum = FindMaximumSubArray(nums, mid+1, high);int crossSum = FindMaxCrossingSubArray(nums, low, mid, high);return max(max(leftSum, rightSum), crossSum);}};


0 0
原创粉丝点击