问题解析
这道题是典型的滑动窗口(Sliding Window)应用场景。我们需要在数组中找到一个连续子数组,使其元素之和大于等于给定的 $x$,并返回该子数组的最小长度对应的起止位置。
核心思路
使用两个指针 prev 和 cur 分别代表窗口的左右边界。
- 扩展窗口:
cur向右移动,将当前元素加入总和sum。 - 收缩窗口:一旦
sum达到或超过目标值 $x$,说明当前窗口满足条件。此时尝试移动prev指针向右,缩小窗口范围,同时更新记录到的最优解。只要sum依然满足条件,就继续收缩,直到不满足为止。 - 记录结果:在收缩过程中,如果当前窗口长度小于已记录的长度,则更新结果索引。
这种双指针方法保证了每个元素最多被访问两次,时间复杂度为 $O(N)$。
代码实现
下面是完整的 C++ 实现,注意处理输入输出格式及边界情况。
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 输入 n 和 x
int n, x;
cin >> n >> x;
vector<int> arr(n, 0);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
// 用于保存最终结果的起始和结束索引
int index[2] = {0};
// 滑动窗口初始化
int cur = 0;
int prev = 0;
int sum = 0;
while (cur < n) {
sum += arr[cur];
// 当窗口和满足条件时,尝试收缩左边界
while (sum >= x) {
(index[] == && index[] == ) {
index[] = prev;
index[] = cur;
sum -= arr[prev++];
;
}
length = index[] - index[];
camplen = cur - prev;
(length == camplen || length > camplen) {
(prev < index[] || length > camplen) {
index[] = prev;
index[] = cur;
}
}
sum -= arr[prev++];
}
cur++;
}
cout << index[] + << << index[] + << endl;
;
}


