LeetCode 热题 100 之第13题 最大子数组和(JavaScript篇)

149 阅读2分钟

传送门:53. 最大子数组和 - 力扣(LeetCode)

🧩 题目

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

🛠️解题代码

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let maxSum = nums[0];        
    let currentSum = 0;          
    for (const currentNum of nums) {
        if (currentSum > 0) {
            currentSum += currentNum;  
        } else {
            currentSum = currentNum;   
        }
        maxSum = Math.max(maxSum, currentSum); 
    }
    return maxSum;

};

核心思想:

我们逐个遍历数组中的元素,维护两个变量:

  • maxSum:记录到目前为止找到的最大子数组和。
  • currentSum:记录当前子数组的和。

步骤如下:

  1. 初始化 maxSum 为第一个元素,currentSum 为 0。
  2. 遍历数组中的每一个元素 currentNum
    • 如果 currentSum > 0:说明当前子数组的和是正的,继续累加是有益的。
    • 否则(currentSum <= 0):说明当前子数组的和是负的或零,继续加下去只会让总和更小,不如从当前元素重新开始。
  3. 每次更新完 currentSum 后,比较 maxSumcurrentSum,更新最大值。
  4. 最后返回 maxSum

🔍 代码逐行讲解

var maxSubArray = function(nums) {
    let maxSum = nums[0];        // 初始最大和为第一个元素
    let currentSum = 0;          // 当前子数组和,初始为 0

    for (const currentNum of nums) {
        if (currentSum > 0) {
            currentSum += currentNum;  // 如果当前和为正,继续累加
        } else {
            currentSum = currentNum;   // 否则从当前数重新开始
        }
        maxSum = Math.max(maxSum, currentSum);  // 更新最大和
    }

    return maxSum;
};

📊 示例执行过程

nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] 为例:

currentNumcurrentSummaxSum
-2-2-2
111
-3-21
444
-134
255
166
-516
456

最终返回 6,正确 ✅


⚠️ 边界情况处理(补充)

当前代码在以下情况可能会出错:

  • nums 是空数组(应该抛错或返回 0)
  • nums 所有元素都是负数(例如 [-3, -1, -2],应返回 -1

如果希望代码更健壮,可以这样改进:

var maxSubArray = function(nums) {
    if (nums.length === 0) return 0;

    let maxSum = nums[0];
    let currentSum = nums[0];

    for (let i = 1; i < nums.length; i++) {
        const currentNum = nums[i];
        currentSum = Math.max(currentNum, currentSum + currentNum);
        maxSum = Math.max(maxSum, currentSum);
    }

    return maxSum;
};

这个版本支持:

  • 空数组检查
  • 所有负数情况也能正确返回最大值

📌 总结

特性描述
时间复杂度O(n)
空间复杂度O(1)
是否原地算法是 ✅
是否动态规划是 ✅
适用场景求连续子数组最大和
算法名称Kadane's Algorithm