


前缀和
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
}