【leetcode】53. 最大子数组和

57 阅读1分钟

leetcode-53.png

寻找数组中连续的元素组合成的最大和
起初准备用前缀和来解决这一题,但是把简单的问题复杂化了,无需那么麻烦

这里的 if (sum < 0) sum = 0 的处理逻辑是,既然当前的和都是负数了,就找一个新的开始,找到一个不为负数的开始,这样的开始肯定比前面的负数更大。

Kadane

var maxSubArray = function (nums) {
    let sum = 0
    let res = -Infinity
    for (let i = 0; i < nums.length; ++i) {
        sum += nums[i]
        // 保存每一次的最大值
        res = Math.max(res, sum)
        // 处理负数情况
        if (sum < 0) sum = 0
    }
    return res
};

分治法

var maxSubArray = function (nums) {
    var helper = function (left, right) {
        if (left === right) return nums[left];
        let mid = Math.floor((left + right) / 2);
        let leftSum = helper(left, mid);
        let rightSum = helper(mid + 1, right);
        
        // 求跨中间的最大子数组和
        let leftMax = -Infinity,
            rightMax = -Infinity;
        let sum = 0;
        for (let i = mid; i >= left; --i) {
            leftMax = Math.max(leftMax, (sum += nums[i]));
        }
        sum = 0;
        for (let i = mid + 1; i <= right; ++i) {
            rightMax = Math.max(rightMax, (sum += nums[i]));
        }
        let crossSum = leftMax + rightMax;
        return Math.max(leftSum, rightSum, crossSum);
    };
    return helper(0, nums.length - 1);
};
解法时间复杂度空间复杂度说明
Kadane 算法O(n)O(1)最优
分治法O(n log n)O(log n)可理解为面试进阶法
暴力法O(n²)~O(n³)O(1)会超时,非主流