题目地址:53.最大子数组和
这是非常经典的动态规划题目。如何去寻找这个子数组和呢?我们可先从数学上的逻辑进行分析:
由于是连续序列,所以每个子数组的和都是从左边往右边相加得到的。很多人在看到这道题时第一想法肯定是暴力求解,即求出所有子数组的和并进行比较,这样时间消耗未免太大。
我们可以将上述过程拆分一下,假设pre(i)表示以下标为i的元素结尾的连续最大子数组和(并未规定子数组的起始位置,仅关心结束为止)。那么pre(i)的取值情况有两种:
- 在这个子数组中,如果i之前的子数组的最大子数组和(即pre(i-1))加上i处的值以后,比nums[i]本身的值要小(即pre(i-1)为负数),那么nums[i]就是当前状态下的最大子数组和;
- 如果i之前的子数组的最大子数组和(即pre(i-1))加上i处的值以后,比nums[i]本身的值要大(即pre(i-1)为正数),那么nums[i]+pre(i-1)即是当前状态下的最大子数组和;
所以我们可以写出以i结尾的最大子数组和的表达式:
pre(i)=max(pre(i-1)+nums[i], nums[i])
按照如上关系就可以求出每一个i所对应的最大子数组和,它们构成了一个集合。整个数组的最大子数组和就是这个集合中的最大值,记为ret。
以下是代码部分:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ret=nums[0];
int pre=0;
for(auto& x:nums)
{
pre=max(pre+x,x);
ret=max(ret,pre);
}
return ret;
}
};