1. 题目背景与核心思路解析
这道来自蓝桥杯2024国赛B组的编程题"套手镯",考察的是双指针算法在环形数组中的应用。题目描述大致是:给定一个由正整数组成的环形数组(即首尾相连),要求找出连续子序列的最大和,且子序列长度不超过给定限制。
双指针算法(又称滑动窗口)是处理这类连续子序列问题的利器。其核心思想是维护一个动态变化的窗口,通过左右指针的移动来高效地计算窗口内的统计量。在环形数组中应用时,需要特别注意边界条件的处理。
2. 环形数组的特殊处理技巧
2.1 环形展开为线性
对于环形数组问题,最常用的技巧是将原数组复制一份接在后面,形成一个长度为2n的线性数组。这样任何环形子序列都对应这个扩展数组中的某个线性子序列。
例如数组[1,2,3]展开为[1,2,3,1,2,3]后:
- 环形子序列[3,1]对应线性子序列[3,1]
- 环形子序列[2,3,1]对应线性子序列[2,3,1]
2.2 窗口大小的限制
题目通常会限制子序列的最大长度k。在展开后的数组中,我们需要保证:
- 窗口长度不超过k
- 窗口右边界不超过n+k-1(因为超过这个位置就会开始重复计算)
3. 双指针实现细节
3.1 前缀和预处理
计算前缀和数组prefix,其中prefix[i]表示前i个元素的和。这样任意子序列a[l..r]的和可以快速计算为prefix[r+1]-prefix[l]。
python复制n = len(arr)
prefix = [0] * (2*n + 1)
for i in range(2*n):
prefix[i+1] = prefix[i] + arr[i % n]
3.2 单调队列优化
使用双端队列维护当前窗口中的最小值,确保能在O(1)时间内获取最优解:
python复制from collections import deque
def max_subarray_sum(arr, k):
n = len(arr)
extended = arr + arr
prefix = [0] * (2*n + 1)
for i in range(2*n):
prefix[i+1] = prefix[i] + extended
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容