题目背景
给定一个正整数数组和一个目标值 x,需要找到和大于等于 x 的最短连续子数组的长度。
算法思路
解决这类'最短连续子数组'问题的经典方法是滑动窗口。我们维护两个指针,分别代表窗口的左边界和右边界。右指针不断向右扩展以累加数值,一旦窗口内的总和达到或超过目标值 x,我们就尝试收缩左边界,看看能否在保持条件满足的前提下缩小窗口范围。
具体流程如下:
初始化左右指针均为 0,累加器 sum 为 0。右指针 cur 每次向右移动一步,将当前元素加入 sum。当 sum 大于等于 x 时,说明找到了一个可行解,此时记录当前的窗口位置。接着,为了寻找更短的窗口,我们尝试移除左指针指向的元素,并将左指针右移,重复检查 sum 是否仍满足条件。如果不再满足,则停止收缩,继续移动右指针。
这个过程保证了我们在遍历数组的同时,动态地维护了所有可能的合法窗口,并从中筛选出长度最小的那个。
代码实现
下面是基于 C++ 的具体实现,重点展示了如何维护窗口状态以及更新最优解。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, x;
cin >> n >> x;
vector<int> arr(n);
for(int i = 0; i < n; i++) {
cin >> arr[i];
}
// 用于存储最终结果的起始和结束索引(0-based)
int index[2] = {0};
// 滑动窗口指针
int cur = 0; // 右指针
int prev = 0; // 左指针
int sum = 0; // 当前窗口和
while(cur < n) {
sum += arr[cur];
// 当窗口和满足条件时,尝试收缩左边界
while(sum >= x) {
// 第一次找到解,直接记录
if(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;
;
}


