题解
2026-03-31 19:19:47
发布于:浙江
11阅读
0回复
0点赞
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false); // 加速输入输出
cin.tie(nullptr); // 解绑cin和cout
int n, k;
cin >> n >> k;
vector<long long> a(n); // 使用long long避免溢出
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
// 计算第一个窗口的和
long long min_sum = 0;
for (int i = 0; i < k; ++i) {
min_sum += a[i];
}
long long current_sum = min_sum;
int best_pos = 1; // 起始位置从1开始
// 滑动窗口遍历剩余数组
for (int i = k; i < n; ++i) {
// 滑动窗口:减去左端元素,加上右端元素
current_sum = current_sum - a[i - k] + a[i];
// 更新最小和及对应位置
// 注意:只有当当前和严格小于min_sum时才更新,
// 这样保证相同和时取最早出现的位置
if (current_sum < min_sum) {
min_sum = current_sum;
best_pos = i - k + 2; // 转换为1-based起始位置
}
}
cout << best_pos << endl;
return 0;
}
问题分析与核心思路
问题本质拆解
这是一个典型的滑动窗口求和问题,需要在长度为n的数组中找到长度恰好为k的连续子数组,使其和最小,并返回其起始下标(1-based)。若有多个解,返回起始位置最小的那个。
关键观察
时间复杂度要求:n最大为2×10⁵,必须使用O(n)时间复杂度的算法
滑动窗口优势:可以在O(n)时间内完成,避免O(nk)的暴力解法超时
数据范围:a[i]可以是负数,不能假设和随窗口移动单调变化
起始位置处理:需要记录最小和对应的最早起始位置
这里空空如也




有帮助,赞一个