寻找数组中连续的元素组合成的最大和
起初准备用前缀和来解决这一题,但是把简单的问题复杂化了,无需那么麻烦
这里的 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) | 会超时,非主流 |