给你一个整数数组 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)
的解法,尝试使用更为精妙的 分治法 求解。
假设数组的长度是
,下标从
到
。
我们用代表以第
个数结尾的「连续子数组的最大和」,那么很显然我们要求的答案就是:
因此我们只需要求出每个位置的,然后返回
数组中的最大值即可。那么我们如何求
呢?我们可以考虑
单独成为一段还是加入
对应的那一段,这取决于
和
的大小,我们希望获得一个比较大的,于是可以写出这样的动态规划转移方程:
不难给出一个时间复杂度、空间复杂度
的实现,即用一个
数组来保存
的值,用一个循环求出所有
。考虑到
只和
相关,于是我们可以只用一个变量
来维护对于当前
的
的值是多少,从而让空间复杂度降低到
,这有点类似「滚动数组」的思想。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0, maxAns = nums[0];
for (const auto &x: nums) {
pre = max(pre + x, x);
maxAns = max(maxAns, pre);
}
return maxAns;
}
};
复杂度
时间复杂度:,其中
为
数组的长度。我们只需要遍历一遍数组即可求得答案。
空间复杂度:。我们只需要常数空间存放若干变量。