任意子数组和的绝对值的最大值-LeetCode
这是一份基于你提供的代码生成的详细题解文档。
1749. 任意子数组和的绝对值的最大值
🎯 问题描述
描述:
给你一个整数数组 nums。
子数组 nums[l...r] 的和定义为 。
你需要找出所有可能的子数组和中,绝对值最大的那一个。
即求 ,其中 。
说明:
-
这是一个前缀和结合数学推导的问题。
-
核心策略:
- 任意子数组的和都可以表示为两个前缀和之差:。
- 我们要最大化 。
- 这等价于在
pre数组中找到两个数,使它们的差值的绝对值最大。 - 显然,这个最大值等于
pre数组中的最大值减去最小值。
-
示例:
-
示例 1:
1 | 输入:nums = [1,-3,2,3,-4] |
💻 解题思路
思路1:前缀和极值差
核心逻辑
- 构建前缀和数组
pre:pre[0] = 0(表示空前缀的和)。pre[i+1] = pre[i] + nums[i]。pre[i]表示nums[0]到nums[i-1]的和。
- 数学转化:
- 任意子数组
nums[l...r]的和可以表示为 。 - 我们需要求 。
- 绝对值 的最大值,一定等于数组中的最大值减去最小值。
- 即 。
- 任意子数组
- 计算结果:
- 直接返回
max(pre) - min(pre)。
- 直接返回
代码实现
1 | class Solution: |
📊 性能分析
- 时间复杂度:
- 构建前缀和数组:。
- 查找最大值和最小值:。
- 总体线性时间。
- 空间复杂度:
- 需要一个长度为 的
pre数组。 - 注:其实可以优化到 空间,只需在遍历过程中维护当前的
min_pre和max_pre即可,不需要存储整个数组。
- 需要一个长度为 的
思考
-
为什么
pre数组要包含0?pre[0] = 0代表空前缀。- 如果不包含
0,我们就无法表示从下标0开始的子数组(即l=0的情况)。 - 例如,如果整个数组的和最大,那么 。
-
数学证明:
- 我们要最大化 ,其中 。
- 情况1:,则 。要最大化它,需 最大, 最小。
- 情况2:,则 。要最大化它,需 最大, 最小。
- 综上,最大值总是 。
-
空间优化版本:
- 由于我们只需要最大值和最小值,不需要回溯具体的子数组,因此不需要存储整个
pre数组。 - 可以在一次遍历中完成:
1
2
3
4
5
6
7
8
9
10
11# 空间优化版本
current_sum = 0
min_pre = 0
max_pre = 0
for num in nums:
current_sum += num
min_pre = min(min_pre, current_sum)
max_pre = max(max_pre, current_sum)
return max_pre - min_pre
- 由于我们只需要最大值和最小值,不需要回溯具体的子数组,因此不需要存储整个
-
与最大子数组和的区别:
- 最大子数组和(Kadane算法)只关心正数累积。
- 本题关心绝对值,所以既要看最大的正累积,也要看最小的负累积(因为 可能很大)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






