最大子序和

问题描述:

给定一个整数数组 nums,要求找到一个连续的子数组(至少包含一个元素),使得该子数组的和最大。返回这个最大和

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 子数组 [4,-1,2,1] 的和最大,为 6。

解决方法

这个问题可以使用动态规划来求解。

动态规划转移方程:

  • 状态定义dp[i] 表示到 nums[i] 时的最大子数组的和。

  • 转移方程:对于每一个 i,有两种选择:

    1. 选择当前元素,也就是nums[i] 单独作为子数组的开始。

    2. 或者将当前元素 nums[i] 加入到之前的子数组中。

    所以,递推关系为:

    dp[i]=max⁡(dp[i−1]+nums[i],nums[i])

    即:

    • 如果 dp[i-1] + nums[i]nums[i] 更大,表示我们将当前元素加到之前的子数组中。

    • 否则,我们从当前元素开始一个新的子数组。

边界条件:

  • 初始化时,dp[0] = nums[0],因为子数组的和就是第一个元素本身。

最终结果:

  • 最终的最大子数组和就是 dp 数组中的最大值。

代码实现:

dp 会随着数组的遍历而动态变化,可能会从较大的值变成较小的值,尤其是当我们遇到一些负数时。

由于我们每一步都在计算“到当前位置为止的最大子数组和”,所以 dp 有可能会减少。

为了确保我们能够找到全局的最大子数组和,我们需要一个全局变量(通常是 maxSum)来保存我们迄今为止遇到过的最大值。

function maxSubArray(nums) {
    // 初始化第一个元素
    let dp = nums[0];
    let maxSum = dp;
    
    // 从第二个元素开始遍历
    for (let i = 1; i < nums.length; i++) {
        dp = Math.max(dp + nums[i], nums[i]);  // 当前子数组和和当前元素
        maxSum = Math.max(maxSum, dp);  //更新全局的最大子数组和
    }
    
    return maxSum;
}
console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4]));  // 输出 6
console.log(maxSubArray([-1, -2, -3, -4]));  // 输出 -1
console.log(maxSubArray([5, 4, -1, 7, 8]));  // 输出 23

 

posted @ 2025-03-26 15:44  我是格鲁特  阅读(15)  评论(0)    收藏  举报