给你一个整数数组 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
思路一 :求区间和,记录最大值。双层for循环枚举区间起始结束点。提前求前缀和预处理,方便求区间和。结果超时
思路二 :区间问题,维护区间状态。考虑双指针。双指针需要考虑何时移动左右指针。如果当前值大于0,一定会加入区间。因为加一个正数会使值更大。如果当前值小于0,分两种情况,区间和sumValue>0,加负值后面还可能大于0;区间和sumValue<0,求和更小,所以左指针移动到当前值。
综上,可以用一个sumValue变量表示区间和,如果sumValue小于0,就让sumValue等于0。当前值为区间起始点,开始求和。
思路一
c
class Solution {
public int maxSubArray(int[] nums) {
int[] preSum = new int[nums.length+1];
for(int i = 1;i<=nums.length;i++){
preSum[i] = preSum[i-1]+nums[i-1];
}
int maxRes = Integer.MIN_VALUE;
for(int i = 0;i<nums.length;i++){
for(int j = i+1;j<=nums.length;j++){
Integer sumValue = preSum[j] - preSum[i];
maxRes = Math.max(maxRes, sumValue);
}
}
return maxRes;
}
}
思路二
c
class Solution {
public int maxSubArray(int[] nums) {
int maxRes = Integer.MIN_VALUE;
int sumValue = 0;
for(int i = 0;i<nums.length;i++){
if(sumValue<0){
sumValue = 0;
}
sumValue += nums[i];
maxRes = Math.max(maxRes, sumValue);
}
return maxRes;
}
}