环形数组的最大子数组和问题
字数 1117 2025-10-28 22:11:24
环形数组的最大子数组和问题
题目描述:
给定一个长度为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]整个数组)
这个解法巧妙地利用了环形数组的特性,通过比较两种情况来得到最终结果。