最大子数组和(Maximum Subarray)JS代码逻辑与异常问题咨询
最大子数组和代码逻辑解析
你给出的求解最大子数组和的代码如下,属于经典的Kadane算法实现:
var maxSubArray = function(nums) { if(nums.length == 0) return 0; let result = Number.MIN_SAFE_INTEGER; let sum = 0; for(let i = 0; i < nums.length; i++) { sum += nums[i]; result = Math.max(sum, result); sum = sum < 0 ? 0 : sum; } return result; }; console.log(maxSubArray([-2,1,-3,4,-1,2,1,-5,4]));
核心变量作用
sum:记录当前正在累加的连续子数组的和result:记录遍历全程中出现过的所有子数组的最大和,初始值设为Number.MIN_SAFE_INTEGER是为了兼容数组全为负数的场景
逐轮执行流程(以测试用例[-2,1,-3,4,-1,2,1,-5,4]为例)
初始状态:sum = 0,result = Number.MIN_SAFE_INTEGER
- 遍历第0位元素
-2:
累加后sum = 0 + (-2) = -2
更新result = max(-2, 最小安全整数) = -2
因sum为负,重置为0 - 遍历第1位元素
1:
累加后sum = 0 + 1 = 1
更新result = max(1, -2) = 1
sum为正,保留原值1 - 遍历第2位元素
-3:
累加后sum = 1 + (-3) = -2result = max(-2, 1) = 1,无变化
因sum为负,重置为0 - 遍历第3位元素
4:
累加后sum = 0 + 4 = 4
更新result = max(4, 1) = 4
sum为正,保留原值4 - 遍历第4位元素
-1:
累加后sum = 4 + (-1) = 3result = max(3, 4) = 4,无变化
sum为正,保留原值3 - 遍历第5位元素
2:
累加后sum = 3 + 2 = 5
更新result = max(5, 4) = 5
sum为正,保留原值5 - 遍历第6位元素
1:
累加后sum = 5 + 1 = 6
更新result = max(6, 5) = 6
sum为正,保留原值6 - 遍历第7位元素
-5:
累加后sum = 6 + (-5) = 1result = max(1, 6) = 6,无变化
sum为正,保留原值1 - 遍历第8位元素
4:
累加后sum = 1 + 4 = 5result = max(5, 6) = 6,无变化
sum为正,保留原值5
遍历结束后返回result = 6,对应最大子数组[4,-1,2,1]的和,结果正确。
修改后代码失效的原因
删除result = Math.max(sum, result);并将返回值改为sum后,逻辑变成仅返回遍历结束时的当前累加和,存在两个明显问题:
- 最大子数组和可能出现在遍历的中间节点,而非最后。以上述测试用例为例,最大和6出现在第6位元素遍历完成时,后续累加元素后sum反而降到了5,直接返回最终sum就会漏掉最大值
- 无法处理全负数数组的场景。比如输入
[-3,-1,-2],修改后的代码最后sum会被重置为0,完全不符合预期,而原代码中的result会记录到最大的单个元素值-1
内容的提问来源于stack exchange,提问作者DAS
相关产品推荐
相关产品推荐

