Skip to content

Latest commit

 

History

History
87 lines (67 loc) · 2.42 KB

53.最大子序和.md

File metadata and controls

87 lines (67 loc) · 2.42 KB

53. 最大子序和

url

题目

给定一个整数数组 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]

  1. 题目说找一个具有最大和的连续子数组,那么必然是要求和的,肯定有求和这一步,那么我们就求和
  2. preSum = -2 + 1 = -1,咦?不对劲,-1还不如1大,我直接舍弃原来的负数把,此时preSum = 1,maxSum = 1
  3. preSum = preSum + -3 = -2,maxSum = 1
  4. preSum = preSum + 4 = 2, 咦?不对劲,还不如舍弃原来的和,直接用该值呢,此时preSum = 4,maxSum = 4
  5. 以此类推,你就会发现,最后maxSum是6,为什么在第三步舍弃-3这个数呢?明明加了-3,preSum变成了-2,毕竟题目说了连续嘛,难不成,你跳过-3哇?所以就有了这么一句话的判断preSum = preSum > 0 ? preSum + nums[i] : nums[i];,意思就是说,以当前和的正负判断,正我就加,负我就舍弃和,从新的值开始。

code

js

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]));
  

go

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
}

java

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;
    }
}