最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
解法1:暴力循环遍历解法:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0) return NULL;
int max=nums[0];//存最大值
int sum=0;//求和
for(int i=0;i<nums.size();i++)
{
sum=0;
for(int j=i;j<nums.size();j++)
{
sum+=nums[j];
if(sum>max) max=sum;
}
}
return max;
}
};
该方法时间复杂度为O(n2)。
解法2:动态规划
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size() == 0) return NULL;
int res = INT_MIN;
int sum = -1;
for(int i = 0; i < nums.size(); ++i)
{
sum = max(nums[i], sum + nums[i]);
res = max(sum, res);
}
return res;
}
};
解法3:分治法(类似二分法)
思路:将数组分为左右两部分,用递归求解方法分别求最大子序和,再将左右两部分和中间值nums[mid]进行整合,先将nums[mid]和左边部分进行整合,再和右边进行整合,用两个for循环;最终得到左半边最大子序和l,右半边最大子序和r,和num_max,这三个的最大值就是最后的答案。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0) return NULL;
return fenzhifa(nums,0,nums.size()-1);
}
int fenzhifa(vector<int>& nums,int left,int right)
{
if(left>right) return INT_MIN;
if(left==right) return nums[left];
int mid=(left+right)/2;
int l=fenzhifa(nums,0,mid-1);//求左半边最大子序和
int r=fenzhifa(nums,mid+1,right);//求右半边最大子序和
int t=nums[mid];
int max_num=nums[mid];
for(int i=mid-1;i>=left;i--)//整合左半部分
{
t+=nums[i];
max_num=max(max_num,t);
}
t=max_num;
for(int i=mid+1;i<=right;i++)//整合右半部分
{
t+=nums[i];
max_num=max(max_num,t);
}
return max(max(r,l),max_num);
}
};
注:该方法较复杂,耗时较长,建议使用方法2动态规划速度快。
觉得本文对你有帮助,点个赞噢谢谢