带变体的Kadane算法问题:寻找最大化V值的数组区间
带区间最小值扣除的最大子数组问题解法
嘿,这个问题是经典最大子数组和的变种,咱们一步步拆解来看:
首先,先复习下基础版:如果没有数组B的要求,这就是咱们熟悉的最大子数组和问题,用Kadane算法就能在O(N)时间里搞定。但现在多了个条件——得从子数组的和里减去该区间内B数组的最小值,难度就上来了一点。
先说说最直接(但低效)的暴力解法
- 思路很简单:双重循环遍历所有可能的
[i,j]区间,对每个区间先算出A数组的子数组和,再找到B数组在这个区间里的最小值,最后计算V = sum(A[i:j]) - min(B[i:j]),全程记录最大的V值就行。 - 但这个方法的时间复杂度是O(N²),当n很大的时候(比如十万甚至百万级别的数据),完全跑不动,只能处理小数据量的场景,肯定不是最优解。
优化思路:从B的最小值入手
既然V的值里,扣除的是区间内B的最小值,那我们可以换个角度——枚举B中的每个元素作为某个区间的最小值,然后找到包含这个元素且以它为最小值的最大区间,再计算这个区间内A的子数组和减去这个B元素的值,最后取所有情况里的最大值。
这里可以用单调栈来高效找到每个B[k]作为最小值的左右边界:
- 用单调递增栈,找到每个元素
B[k]左边第一个比它小的元素位置left[k],右边第一个小于等于它的元素位置right[k](边界规则可以根据去重需求微调,避免重复计算相同最小值的区间) - 这样,以
B[k]为最小值的有效区间范围就是(left[k]+1, right[k]-1) - 接下来需要在这个区间内找到A的最大子数组和,再减去
B[k],得到这个情况下的V值 - 遍历所有k,取所有V值里的最大值就是答案
为了快速计算A的子数组和,我们可以先预处理A的前缀和数组,这样任意区间的和都能在O(1)时间内算出。另外,结合类似Kadane的思路,还能进一步优化区间内最大子数组和的计算效率。
另外,也可以用动态规划的思路来做:
- 定义
dp[i]为以i结尾的区间的最大V值 - 对于每个i,用单调栈维护当前可能的最小值候选,从而快速更新
dp[i],避免重复计算
复杂度对比
- 暴力解法:O(N²),仅适合小数据
- 单调栈+前缀和/Kadane的优化解法:O(N),能轻松处理大规模数据
内容的提问来源于stack exchange,提问作者Cihan
相关产品推荐
相关产品推荐

