最开始想的是,我用双指针的方式一前一后进行遍历,如果区间内的数值大于0,就将快指针+1,否则将慢指针+1,直至区间内的值为正。这样写会有一个问题,那就是我默认区间最大值为正值。这种默认是不对的。
所以将算法改为dp,dp 的特点我感觉和递归类似,都是可以将问题分解为相同目标的子问题,将规模缩小,然后再一步步的扩展到正常规模,中间用记忆化数组对其进行加速。
因为题目要求为连续子序列,那么数组中第i个元素就之和第i-1个元素相关。dp公式就很好写。
dp[i] = max(dp[i-1]+nums[i],nums[i])
意义就是第i个元素可以选择两种方式,第一种是和前i-1个元素一起组成一个区间,另一种放弃前i-1个元素,自己组成一个区间。取其中大的,一步步向后。时间复杂度为O(m),m为数组大小,空间复杂度也为O(m)。
可以将其改为空间复杂度O(1),因为dp数组中的元素之和上一次算出来的值相关,所以就可以用一个值来代替整个数组。
class Solution
{
public:
int maxSubArray(vector<int> &nums)
{
int len = nums.size();
if (len == 0)
return 0;
int cur = nums[0], res = nums[0];
for (int i = 1; i < len; i++)
{
cur = max(cur + nums[i], nums[i]);
res = max(res, cur);
}
return res;
}
};