53. 最大子数组和
mengjian-github opened this issue · comments
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23】
这道题最直观的想法是暴力求解,尝试把每个子数组的情况全部计算出来取最大:
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
if (nums.length <= 1) {
return nums[0];
}
function getMax(index) {
const num = nums[index];
let sum = num;
let max = num;
// 计算以num开头的连续最大和
for (let i = index + 1; i < nums.length; i++) {
sum += nums[i];
if (sum > max) {
max = sum;
}
}
return max;
}
let result = nums[0];
for (let i = 0; i < nums.length; i++) {
const max = getMax(i);
if(max > result) {
result = max;
}
}
return result;
};
不幸的是,这个复杂度通不过LeetCode
这里采用动态规划是最简单直观的做法,但是dp数组的定义比较特殊:
- dp数组的含义是以i结尾的最长子数组和,这样才能让dp具有递推关系
- 递推关系是:dp[i+1] = Math.max(dp[i] + nums[i+1], nums[i+1]),相当于要么和之前的数组结合在一起,要么自己新起一个
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
let result = nums[0];
const dp = [nums[0]]; // dp的定义是,以i结尾的最大子数组和
for (let i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
if (dp[i] > result) {
result = dp[i];
}
}
return result;
};