【LeetCode】53. 最大子数组和

leetcode

 

解题思路

​​最大子序和问题​​要求找到一个连续子数组,使其元素和最大。核心思路是使用​​动态规划​​或​​贪心策略​​:

  • ​​核心观察​​:以 nums[i] 结尾的最大子序和,要么是 nums[i] 自身,要么是 nums[i] 加上以 nums[i-1] 结尾的最大子序和(若后者为正)。
  • ​​贪心策略​​:遍历数组时维护当前子序和 curSum。若 curSum 变为负数,则重置为当前元素(负数会拖累后续和),否则累加元素。同时用 maxSum 记录全局最大值。

关键步骤

  1. ​​初始化​​:

    • curSum = nums[0]:以首元素为起点的子序和。
    • maxSum = nums[0]:全局最大和(处理全负数数组)。
  2. ​​遍历数组​​(从第2个元素开始):

    • ​​更新当前子序和​​:
      • 若 curSum > 0,则累加当前元素:curSum += nums[i](正数增益后续和)。
      • 若 curSum ≤ 0,则重置为 nums[i](负数拖累,从新起点开始)。
    • ​​更新全局最大和​​:maxSum = max(maxSum, curSum)
  3. ​​返回结果​​:maxSum 即为答案。


代码实现

func maxSubArray(nums []int) int {
    if len(nums) == 0 {
        return 0
    }

    curSum := nums[0] // 当前子序和(以当前元素结尾)
    maxSum := nums[0] // 全局最大和(处理全负数情况)

    // 从第二个元素开始遍历
    for i := 1; i < len(nums); i++ {
        // 若当前子序和为负,重置当前元素(负数拖累后续和)
        if curSum <= 0 {
            curSum = nums[i]
        } else {
            curSum += nums[i]
        }

        // 更新全局最大和
        if curSum > maxSum {
            maxSum = curSum
        }
    }
    return maxSum
}

代码解析:

  • ​​初始化​​:curSum 和 maxSum 均设为 nums[0],确保全负数数组时能返回最大负数。
  • ​​遍历更新​​:
    • curSum <= 0 时,重置为 nums[i](如 [-3, -1] 中,-3 会拖累后续,从 -1 重新开始)。
    • curSum > 0 时,累加 nums[i](如 [4, -1, 2] 中,4 + (-1) = 3 > 0,继续累加 2 得到 5)。
  • ​​全局更新​​:每一步比较 curSum 和 maxSum,确保不遗漏任何可能的子序和。

示例测试

func main() {
    // 示例1: 输出6 (子数组 [4,-1,2,1])
    nums1 := []int{-2, 1, -3, 4, -1, 2, 1, -5, 4}
    fmt.Println(maxSubArray(nums1))

    // 示例2: 输出1 (子数组 [1])
    nums2 := []int{1}
    fmt.Println(maxSubArray(nums2))

    // 示例3: 输出23 (子数组 [5,4,-1,7,8])
    nums3 := []int{5, 4, -1, 7, 8}
    fmt.Println(maxSubArray(nums3))

    // 边界测试: 全负数数组,输出-1
    nums4 := []int{-3, -1, -5, -2}
    fmt.Println(maxSubArray(nums4))
}

复杂度分析

​​维度​​​​结果​​​​说明​​
​​时间复杂度​​ O(n) 遍历数组一次,每个元素处理时间为 O(1) 。
​​空间复杂度​​ O(1) 仅使用常数额外空间(curSummaxSum)。

关键点总结

  1. ​​贪心策略​​:

    • 当前子序和为负时立即重置,避免拖累后续和(核心优化点)。
    • 正数累加可扩大子序和,负数需独立判断。
  2. ​​边界处理​​:

    • 初始化 maxSum = nums[0]:确保全负数数组时返回最大元素(如 [-3, -1] 返回 -1)。
    • 空数组直接返回 0(题目要求子数组至少含一个元素,但代码需健壮性)。
  3. ​​与动态规划等价​​:

    • 本质是动态规划的空间优化版,状态转移方程:
      ​​curSum = max(nums[i], curSum + nums[i])​​。 
  4. ​​适用场景​​:

    • 高效处理大规模数据(n ≤ 3×10⁴)。
    • 分治法(O(nlogn))更复杂,此解法更优。
posted @ 2025-06-24 15:40  云隙之间  阅读(65)  评论(0)    收藏  举报