题目链接:https://leetcode.com/problems/maximum-subarray/
题目描述:
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
.
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> sum;
sum.push_back(nums[0]);
int re=sum[0];
for(int i=1;i<nums.size();i++)
{
sum.push_back(sum[i-1]+nums[i]>nums[i]?sum[i-1]+nums[i]:nums[i]);
if(sum[i]>re)
re=sum[i];
}
return re;
}
};
参考链接:动态规划
http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741374.html
(第二次遇到补充:)思路二:还是动态规划的思路,但是从另一个方面考虑,最大子序列和可能出现在三处地方:或者整个出现在输入数据的左半部,或者整个出现在右半部,或者跨越输入数据的中部而占据左右两半部分。前两种情况可以用递归求解。第三种情况的最大和可以通过求前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的第一个元素)而得到,然后将这两个部分加在一起。
此种方法比较复杂,时间复杂度:O(NlogN)
代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int maxVal=0;
DC(nums,0,nums.size()-1,maxVal);
return maxVal;
}
void DC(vector<int>& nums, int start, int end,int& maxVal)
{
if (start >=end)
{
if (start==end)
maxVal=nums[start];
return;
}
int left =0,right=0;
DC(nums, start, (start+end) / 2,left);
DC(nums, (start+end)/ 2 + 1, end,right);
maxVal = max(left, right);
int thissum = 0;
int midleft = nums[(start+end) / 2];
for (int i = (start+end) / 2; i >=start; i--)
{
thissum += nums[i];
if (thissum > midleft)
midleft = thissum;
}
thissum = 0;
int midright = nums[(start+end) / 2 + 1];
for (int i = (start+end) / 2 + 1; i <=end; i++)
{
thissum += nums[i];
if (thissum > midright)
midright = thissum;
}
int mid = midleft + midright;
maxVal = max(maxVal, mid);
return;
}
};
思路三:觉得本质上和思路一其实是一样的,就是角度不同,并且不用开辟额外的空间存储。所以思路三的算法是联机算法,仅需常量空间并以线性时间运行的练级算法几乎是完美算法。
代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result=nums[0];//之所以不初始化为0,是因为序列可能出现全负的情况
int tmpsum=0;
for(int i=0;i<nums.size();i++)
{
tmpsum+=nums[i];
if(tmpsum>result)
result=tmpsum;
if(tmpsum<0)
tmpsum=0;
}
return result;
}
};