1749. 任意子数组和的绝对值的最大值
考点
- 最大子数组和
思路
一、问题描述
给定一个长度为 \(n\) 的整数数组 \[ \texttt{nums} = [a_1, a_2, \dots, a_n] \] 要求在所有非空连续子数组中,找到其元素和的绝对值最大值,即: \[ \max_{1 \le l \le r \le n} \left| \sum_{i=l}^{r} a_i \right| \]
二、问题建模
1. 等价拆分
绝对值最大值可以拆成两个独立问题: \[ \max \left( \max_{l,r} \sum_{i=l}^{r} a_i, \; -\min_{l,r} \sum_{i=l}^{r} a_i \right) \] 也就是说:
- 最大子数组和
- 最小子数组和(绝对值取反)
只要同时求出这两者,答案即可直接得到。
2. 子数组和的经典模型
这是一个典型的 最大子数组和(Kadane)模型:
设 \[ dp^{\max}_i = \text{以 } i \text{ 结尾的最大子数组和} \]
状态转移: \[ dp^{\max}_i = \max(a_i, dp^{\max}_{i-1} + a_i) \]
同理,最小子数组和:
设 \[ dp^{\min}_i = \text{以 } i \text{ 结尾的最小子数组和} \]
状态转移: \[ dp^{\min}_i = \min(a_i, dp^{\min}_{i-1} + a_i) \]
三、算法思路
1. 动态规划压缩
不需要维护完整的 DP 数组,只需记录:
pre_mx:当前以位置 \(i\) 结尾的最大子数组和pre_mi:当前以位置 \(i\) 结尾的最小子数组和
以及全局最优值:
mx:所有位置中出现过的最大子数组和mi:所有位置中出现过的最小子数组和
2. 初始化
初始时,子数组至少包含一个元素:
1
2pre_mx = nums[0];
pre_mi = nums[0];全局答案允许“什么都不选”(即 0),因此:
1
2mx = max(0, pre_mx);
mi = min(0, pre_mi);
3. 状态转移(单次遍历)
对每个元素 nums[i]:
更新最大子数组和: \[ pre\_mx = \max(nums[i], pre\_mx + nums[i]) \]
更新最小子数组和: \[ pre\_mi = \min(nums[i], pre\_mi + nums[i]) \]
同步维护全局最优值: \[ mx = \max(mx, pre\_mx) \]
\[ mi = \min(mi, pre\_mi) \]
4. 最终答案
\[ \text{answer} = \max(mx, -mi) \]
四、正确性说明(简要)
- 任意连续子数组要么产生最大的正和,要么产生最小的负和
- Kadane 算法保证枚举了所有以每个位置结尾的最优子数组
- 同时维护最大与最小,即完整覆盖绝对值两侧
- 因此算法正确
五、复杂度分析
时间复杂度: \[ O(n) \]
空间复杂度: \[ O(1) \]
六、AC代码
1 | class Solution { |