题目描述:
给定一个整数数组
nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例:
输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
算法:
动态规划
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0)
return 0;
if(nums.size()==1)
return nums[0];
vector<int>dp(nums.size());
dp[0] = nums[0];
int Max = max(INT_MIN, dp[0]);
for(int i=1; i<nums.size(); i++)
{
if(dp[i-1]>0)
dp[i] = dp[i-1]+nums[i];
else
dp[i] = nums[i];
Max = max(dp[i], Max);
}
return Max;
}
};
进阶:
这个分治法的思想就类似于二分搜索法,
- 我们需要把数组一分为二,分别找出左边和右边的最大子数组之和,
- 然后还要从中间开始向左右分别扫描,
- 求出的最大值分别和左右两边得出的最大值相比较取最大的那一个,
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0)
return 0;
return divide(nums, 0, nums.size()-1);
}
int divide(vector<int>nums, int left, int right)
{
if(left >= right)
return nums[left];
int mid = (right-left)/2 + left;
int lmax = divide(nums, left, mid-1);
int rmax = divide(nums, mid+1, right);
int mmax = nums[mid];
int t = mmax;
for(int i=mid-1; i>=left; i--)
{
t+=nums[i];
mmax = max(t, mmax);
}
t = mmax;
for(int i=mid+1; i<=right; i++)
{
t += nums[i];
mmax = max(mmax, t);
}
return max(mmax, max(lmax, rmax));
}
};