53.最大子数组和
给定一个整型数组 nums
,找出和最大的连续的子数组(包含至少一个数)并返回。
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
进阶:
如果你找到了O(n)复杂度的解决方案,尝试用更巧妙的分治法来码出另一种解决办法。
解法1:
数组最大子数组和有两种情况,一种是只有非正数的数组,这种情况下解是该数组中值最大的元素。另一种是含有正数的数组,这种情况需要进行累加比较。迭代解法:
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
let max = nums[0];
let sum = 0;
for(let num of nums) {
if (sum >= 0) {
sum += num;
} else {
sum = num;
}
if (sum > max) max = sum;
}
return max;
};
解法2:
分治法。在数组中任取一点作为基点(为了提高效率,一般取中点),那么所求解有三种情况:存在于基点左边的子数组中、存在于基点右边的子数组中和存在于横跨基点(以基点为基础向左右两边取最大)左右两边的子数组中。递归解法:
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
function findMax(arr, low, base, high) {
let lMax = arr[base];
let rMax = arr[base + 1];
for (let i = base, sum = 0; i >= low; i--) {
sum += arr[i];
if (sum > lMax) lMax = sum;
}
for (let i = base + 1, sum = 0; i <= high; i++) {
sum += arr[i];
if (sum > rMax) rMax = sum;
}
return lMax + rMax;
}
function findSubMax(arr, begin, end) {
if (begin == end) return arr[begin];
let mid = parseInt(end - (end - begin) / 2);
let leftSum = findSubMax(arr, begin, mid);
let rightSum = findSubMax(arr, mid + 1, end);
let midSum = findMax(arr, begin, mid, end);
return Math.max(leftSum, rightSum, midSum);
}
return findSubMax(nums, 0, nums.length - 1);
};