Given an integer array nums
, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
例子:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
难度:【easy】
思路:最开始能够最先想到的方法就是暴力的方法,将所有的subarray全部枚举出来,取和最大的就是结果。这种方法在不做任何优化的情况下,需要三层循环,最外层循环确定每次subarray的开始位置,中间层循环确定每次sub的结束位置,最内层循环从起始位置到结束位置进行遍历求和。时间复杂度O(n^3). 之后进一步可以想到将中间层和最内层循环合并为一层循环。因为这两层循环进行累加的开始位置相同,只是结束位置不同而已,每次多加一个元素就可以了。这样时间复杂度变成了O(n^2). 之后再想能不能优化到O(n). 下面有两种O(n)的方法:
方法1:一个变量存放最大值,一个变量存放当前的和。遍历数组,如果当前的sum小于等于0,就重新累加,因为前面累加和小于等于0对整个子字符串和不具有增加作用,所以可以直接去掉,反之,继续加。
如果当前的sum大于max就更新max。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max = INT_MIN;
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
if (sum <= 0) {
sum = nums[i];
} else {
sum += nums[i];
}
if (sum > max) {
max = sum;
}
}
return max;
}
};
方法2:dp的思路,对于每个元素都是要么加进去,要么重新开始。
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
int max_sum = dp[0];
for (int i = 1; i < nums.size(); ++i) {
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
max_sum = max(max_sum, dp[i]);
}
return max_sum;
}