给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
这道题算是动态规划的一种,只不过没有用记忆数组去存,而是用记忆变量去存
可以观察这个数组:[-2,1,-3,4,-1,2,1,-5,4]
- 题目说找一个具有最大和的连续子数组,那么必然是要求和的,肯定有求和这一步,那么我们就求和
preSum = -2 + 1 = -1
,咦?不对劲,-1还不如1大,我直接舍弃原来的负数把,此时preSum = 1
,maxSum = 1
preSum = preSum + -3 = -2
,maxSum = 1
preSum = preSum + 4 = 2
, 咦?不对劲,还不如舍弃原来的和,直接用该值呢,此时preSum = 4
,maxSum = 4
- 以此类推,你就会发现,最后maxSum是6,为什么在第三步舍弃-3这个数呢?明明加了-3,preSum变成了-2,毕竟题目说了连续嘛,难不成,你跳过-3哇?所以就有了这么一句话的判断
preSum = preSum > 0 ? preSum + nums[i] : nums[i];
,意思就是说,以当前和的正负判断,正我就加,负我就舍弃和,从新的值开始。
let maxSubArray = (nums) => {
if (nums === undefined || nums.length === 0)
return -1;
let preSum = nums[0];
let maxSum = preSum;
for (let i = 1; i < nums.length; i++) {
preSum = preSum > 0 ? preSum + nums[i] : nums[i];
maxSum = Math.max(maxSum, preSum);
}
return maxSum;
}
console.log(maxSubArray([-2,1,-3,4,-1,2,1,-5,4]));
func maxSubArray(nums []int) int {
if nums == nil || len(nums) == 0 {
return -1
}
preSum, maxSum := nums[0], nums[0]
for i := 1; i < len(nums); i++ {
if preSum > 0 {
preSum = preSum + nums[i]
} else {
preSum = nums[i]
}
maxSum = Max(maxSum, preSum)
}
return maxSum
}
class Solution {
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0)
return -1;
int preSum = nums[0];
int maxSum = preSum;
for (int i = 1; i < nums.length; i++) {
preSum = preSum > 0 ? preSum + nums[i] : nums[i];
maxSum = Math.max(maxSum, preSum);
}
return maxSum;
}
}