一、题目要求
给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组
是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1] 输出:1
示例 3:
输入:nums = [5,4,-1,7,8] 输出:23
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
进阶:如果你已经实现复杂度为 O(n)
的解法,尝试使用更为精妙的 分治法 求解。
二、解法1 O(N)
用max维护当前最大值,tmp维护可能出现的最大值。
(1)如果tmp是负数,将要加的值也是负数,加起来会更小,那么可以直接舍弃掉之前的和
(2)如果tmp是非负数,将要加的值也是非负数,那么加起来肯定不会更小,那么tmp直接加上这个值
(3)如果tmp是非负数,将要加的值是负数,并且tmp+nums[i] < 0,它就会让后面的和变小,所以让tmp等于这个负数,下次循环时tmp就会被处理。
(4)如果tmp是非负数,将要加的值是负数,并且tmp+nums[i] >= 0,它就可以让和更大,所以tmp加上这个值
(5)每次循环都更新max
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max = nums[0];
int tmp = nums[0];
for(int i = 1;i < nums.size();i++)
{
if(tmp < 0)
{
tmp = nums[i];
}
else if(nums[i] >= 0)
{
tmp+=nums[i];
}
else if(nums[i] < 0 && nums[i]+tmp<0)
{
tmp = nums[i];
}
else if(nums[i] < 0 && nums[i]+tmp>=0)
{
tmp += nums[i];
}
if(max < tmp)
max = tmp;
}
return max;
}
};