环形数组的最大子数组和问题
字数 1117 2025-10-28 22:11:24

环形数组的最大子数组和问题

题目描述:
给定一个长度为n的环形整数数组nums,环形数组意味着第一个元素和最后一个元素相邻。请计算环形数组中的最大子数组和(子数组要求是连续的一段)。

注意:子数组最少包含一个元素。

解题过程:

  1. 问题分析:

    • 在普通数组中,最大子数组和可以用Kadane算法在O(n)时间内解决
    • 但在环形数组中,最大子数组和可能出现在两种位置:
      a) 不跨越首尾:即普通的最大子数组和
      b) 跨越首尾:即数组首部的一部分 + 数组尾部的一部分
  2. 关键观察:

    • 情况a(不跨越首尾):直接使用Kadane算法求最大子数组和
    • 情况b(跨越首尾):这种情况等价于总和减去中间部分的最小和
      • 最大子数组和 = 数组总和 - 最小子数组和
      • 注意:如果整个数组都是负数,需要特殊处理
  3. 动态规划定义:

    • max_dp[i]:以第i个元素结尾的最大子数组和
    • min_dp[i]:以第i个元素结尾的最小子数组和
    • 全局最大值 = max(最大子数组和, 总和 - 最小子数组和)
  4. 状态转移方程:

    • max_dp[i] = max(nums[i], max_dp[i-1] + nums[i])
    • min_dp[i] = min(nums[i], min_dp[i-1] + nums[i])
  5. 边界条件:

    • max_dp[0] = min_dp[0] = nums[0]
    • total_sum = 所有元素之和
  6. 特殊情况处理:

    • 如果整个数组都是负数,最大子数组和就是数组中的最大元素
    • 这种情况的判断:当max_dp的最大值 ≤ 0时
  7. 算法步骤:
    a) 计算数组总和total_sum
    b) 初始化max_dp[0]和min_dp[0]为nums[0]
    c) 遍历数组,计算每个位置的max_dp和min_dp
    d) 记录max_dp中的最大值max_val和min_dp中的最小值min_val
    e) 如果max_val ≤ 0,返回max_val(全是负数的情况)
    f) 否则返回max(max_val, total_sum - min_val)

  8. 时间复杂度:O(n)

  9. 空间复杂度:可以优化到O(1),因为只需要前一个状态

示例说明:
输入:[5, -3, 5]

  • 情况a(不跨越):最大子数组和为5(第一个5)或5(最后一个5)
  • 情况b(跨越):总和=7,最小子数组和=-3,跨越情况的和=7-(-3)=10
  • 最终结果:max(5, 10) = 10(即[5, -3, 5]整个数组)

这个解法巧妙地利用了环形数组的特性,通过比较两种情况来得到最终结果。

环形数组的最大子数组和问题 题目描述: 给定一个长度为n的环形整数数组nums,环形数组意味着第一个元素和最后一个元素相邻。请计算环形数组中的最大子数组和(子数组要求是连续的一段)。 注意:子数组最少包含一个元素。 解题过程: 问题分析: 在普通数组中,最大子数组和可以用Kadane算法在O(n)时间内解决 但在环形数组中,最大子数组和可能出现在两种位置: a) 不跨越首尾:即普通的最大子数组和 b) 跨越首尾:即数组首部的一部分 + 数组尾部的一部分 关键观察: 情况a(不跨越首尾):直接使用Kadane算法求最大子数组和 情况b(跨越首尾):这种情况等价于总和减去中间部分的最小和 最大子数组和 = 数组总和 - 最小子数组和 注意:如果整个数组都是负数,需要特殊处理 动态规划定义: max_ dp[ i ]:以第i个元素结尾的最大子数组和 min_ dp[ i ]:以第i个元素结尾的最小子数组和 全局最大值 = max(最大子数组和, 总和 - 最小子数组和) 状态转移方程: max_ dp[ i] = max(nums[ i], max_ dp[ i-1] + nums[ i ]) min_ dp[ i] = min(nums[ i], min_ dp[ i-1] + nums[ i ]) 边界条件: max_ dp[ 0] = min_ dp[ 0] = nums[ 0 ] total_ sum = 所有元素之和 特殊情况处理: 如果整个数组都是负数,最大子数组和就是数组中的最大元素 这种情况的判断:当max_ dp的最大值 ≤ 0时 算法步骤: a) 计算数组总和total_ sum b) 初始化max_ dp[ 0]和min_ dp[ 0]为nums[ 0 ] c) 遍历数组,计算每个位置的max_ dp和min_ dp d) 记录max_ dp中的最大值max_ val和min_ dp中的最小值min_ val e) 如果max_ val ≤ 0,返回max_ val(全是负数的情况) f) 否则返回max(max_ val, total_ sum - min_ val) 时间复杂度:O(n) 空间复杂度:可以优化到O(1),因为只需要前一个状态 示例说明: 输入:[ 5, -3, 5 ] 情况a(不跨越):最大子数组和为5(第一个5)或5(最后一个5) 情况b(跨越):总和=7,最小子数组和=-3,跨越情况的和=7-(-3)=10 最终结果:max(5, 10) = 10(即[ 5, -3, 5 ]整个数组) 这个解法巧妙地利用了环形数组的特性,通过比较两种情况来得到最终结果。