53. Maximum Subarray

25 年 10 月 18 日 星期六
527 字
3 分钟

53. Maximum Subarray

Screenshot 2025-10-18 at 12.38.44 am
Screenshot 2025-10-18 at 12.54.00 am
Screenshot 2025-10-18 at 12.54.17 am

https://leetcode.cn/problems/maximum-subarray/solutions/2361770/53-zui-da-zi-shu-zu-he-dong-tai-gui-hua-bvkq9

前缀和

js
/**
 * @param {number[]} nums
 * @return {number}
 */
/**
 * 求解数组的最大子数组和(前缀和 + 维护最小前缀和方法)
 * @param {number[]} nums - 输入的整数数组(可能包含负数)
 * @return {number} - 数组中连续子数组的最大和
 */
var maxSubArray = function (nums) {
  // 1. 初始化全局最大子数组和为负无穷
  // (因为数组可能全为负数,初始值要足够小才能被正确更新)
  let ans = -Infinity

  // 2. 初始化最小前缀和为0
  // (前缀和从0开始,对应“不选任何元素”的情况,处理子数组从第一个元素开始的场景)
  let minPreSum = 0

  // 3. 初始化当前前缀和为0
  // (前缀和:nums[0] + nums[1] + ... + nums[i])
  let preSum = 0

  // 4. 遍历数组中的每个元素
  // 我们的核心逻辑是:以x结尾的最大子数组和 = 到x的前缀和(preSum) - 到x之前某个位置的最小前缀和(minPreSum)
  //这里的关键是:minPreSum 必须是不包含 x的前缀和(也就是 x 之前所有前缀和中的最小值),如果把 x 的前缀和提前加入 minPreSum,就会出现 “自己减自己” 的错误。
  for (const x of nums) {
    // 4.1 累加当前元素,更新到当前前缀和
    // 此时preSum表示:从数组开头到当前元素x的总和
    preSum += x

    // 4.2 计算以当前元素x结尾的最大子数组和,并更新全局最大值ans
    // 逻辑:preSum(到x的前缀和) - minPreSum(前面最小的前缀和)= 以x结尾的最大子数组和
    // 例如:preSum=5,minPreSum=1 → 5-1=4(对应从minPreSum的下一个元素到x的子数组和为4)
    ans = Math.max(ans, preSum - minPreSum)

    // 4.3 维护最小前缀和:比较当前minPreSum和preSum,保留更小的值
    // 确保后续计算时,能拿到“到当前位置为止”最小的前缀和
    minPreSum = Math.min(minPreSum, preSum)
  }

  // 5. 返回全局最大子数组和
  return ans
}

文章标题:53. Maximum Subarray

文章作者:Sirui Chen

文章链接:https://blog.siruichen.me/posts/53_maximum_subarray[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。