class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max = nums[0];
int tmpSum = 0;
int index = 0;
while (max < 0) {
while (index < nums.size()) {
if (nums[index] > max) {
max = nums[index];
break;
}
index += 1;
}
if (index >= nums.size()) break;
}
for (int i = index; i < nums.size(); ) {
for (index = i; index < nums.size(); index++){
tmpSum += nums[index];
if (tmpSum < 0) {
i = index + 1;
tmpSum = 0;
break;
} else if (tmpSum > max) {
max = tmpSum;
}
if (index == nums.size() - 1) {
return max;
}
}
}
return max;
}
};
思路
遍历数组,找到第一个大于0的数;
累加该数之后的值,如果小于零,从下一个数开始重新累加;如果大于最大值,则赋值;如果是其他,继续累加;
累加到数组的最后一个元素结束;
分析
上述过程一定能找到最大值:
首先,全数组小于零的情况先处理;(必只有一个元素组成最大值)
假设数组至少有一个正数,必能找到第一个正数;
在部分和恒正的一段数组上,用上述方法寻找最大值,若有其中一段的和最大且不为我们的结果,由我们的寻找方法,前面部分和恒正,从而添加上前面的一段,必然更大,从而矛盾;
若出现部分和负数,则最大值必然断开在多段中,只要找到其中的最大段即可;
要点
两重while循环先处理数组全负或找到第一个正数的情况;
局部变量i不会达到终止条件,若index遍历到数组尾部,直接返回结果;
动态规划降维打击
用 f(i) 代表以第 i 个数结尾的「连续子数组的最大和」
则f(i)为f(i-1) + nums[i],nums[i]中的最大值,选其中的最大值即可;