求解子数组奇偶索引元素和的最大差值问题
子数组偶索引和与奇索引和的最大差值解法
问题描述
给定一个长度为N的整数数组(元素可正可负),采用0-based索引规则,计算任意子数组的偶数索引元素和减去奇数索引元素和的最大差值。
示例
输入数组:A = [ 1, 2, -1, 4, -1, -5 ]
最优子数组为:[ 2, -1, 4, -1 ]
计算过程:
子数组偶数索引(0-based)元素和:2 + 4 = 6 子数组奇数索引(0-based)元素和:(-1) + (-1) = -2 总差值:6 - (-2) = 8
解法思路
我们可以通过数学变形把问题转化为前缀和最值问题,实现O(N)时间复杂度求解:
- 差值表达式变形:假设选中的子数组对应原数组下标范围为
[l, r],子数组的偶索引和减奇索引和可以等价为:- 若
l为偶数:preSum[r+1] - preSum[l] - 若
l为奇数:preSum[l] - preSum[r+1]
其中preSum是预处理的前缀和数组,preSum[0] = 0,preSum[i] = preSum[i-1] + A[i-1] * (-1) ** (i-1)
- 若
- 后缀最值优化:从后往前遍历所有可能的起点
l,维护当前位置之后前缀和的最大值和最小值,直接计算每个起点能得到的最大差值,全局记录最大值即可。
代码实现(Python)
def max_even_minus_odd_diff(arr): n = len(arr) pre_sum = [0] * (n + 1) for i in range(1, n + 1): pre_sum[i] = pre_sum[i-1] + arr[i-1] * ((-1) ** (i-1)) max_suffix = pre_sum[-1] min_suffix = pre_sum[-1] max_diff = float('-inf') for l in range(n-1, -1, -1): if l % 2 == 0: current = max_suffix - pre_sum[l] else: current = pre_sum[l] - min_suffix if current > max_diff: max_diff = current # 更新后缀最值 if pre_sum[l] > max_suffix: max_suffix = pre_sum[l] if pre_sum[l] < min_suffix: min_suffix = pre_sum[l] return max_diff # 测试示例 A = [1,2,-1,4,-1,-5] print(max_even_minus_odd_diff(A)) # 输出8
复杂度分析
- 时间复杂度:O(N),仅需两次线性遍历数组
- 空间复杂度:O(N),存储前缀和数组,若进一步优化可将空间复杂度降为O(1),无需存储完整前缀和数组,边遍历边计算即可
内容的提问来源于stack exchange,提问作者Parth Pratim Chatterjee
相关产品推荐
相关产品推荐

