题目描述
给定一个包含 n 个正整数的数组和一个目标值 x,请找出和大于等于 x 的最短连续子数组,并输出其起始和结束位置(从 1 开始计数)。
解题思路
这道题是典型的滑动窗口问题。核心在于维护一个动态区间 [prev, cur],通过移动左右指针来调整区间和。
具体策略如下:
- 初始化:定义两个指针 prev 和 cur,初始均为 0,sum 记录当前窗口内的元素总和。
- 扩张窗口:cur 向右移动,将新元素加入 sum。
- 收缩窗口:当 sum >= x 时,说明当前窗口满足条件。此时需要尝试缩小窗口以寻找更优解。记录当前的 prev 和 cur 作为潜在结果,然后减去 arr[prev] 并将 prev 右移。
- 重复:只要 sum 仍满足条件,继续收缩;否则继续扩张 cur。
注意代码中对于索引记录的细节,需确保在找到更短或同等长度但更靠前的区间时更新结果。
代码实现
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 输入处理
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) {
// 第一次找到有效区间
if (index[0] == && 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;
;
}


