暴力做法:
#include <iostream>
using namespace std;
int main()
{
int n, l;
int s[1000];
cin >> n >> l;
for (int i = 0; i < n; i++)
cin >> s[i];
for (int i = 0; i <= n - l; i++)
{//外层循环遍历每一个起始点
int k = s[0];
for (int j = 0; j < l; j++)
{
if (s[j] < k)
k = s[j];
}
cout << k << endl;
}
return 0;
}
来自学长的代码:(注释仅代表本人的见解)
#include <bits/stdc++.h> // 包含通用的C++标准库头文件
using namespace std;
int n, m; // n表示数组长度,m表示滑动窗口大小
int a[100010]; // 存储输入的整数数组
int q[100010], hea = 1, tai = 0; // 单调队列,hea表示队列头部位置,tai表示队列尾部位置
int main() {
cin >> n >> m; // 从标准输入读取n和m
// 读取数组a的元素
for (int i = 1; i <= n; i++) {
cin >> a[i]; // 读取第i个元素的值
// 维护单调递减队列
while (1) {
// 如果当前元素小于队尾元素且队列非空,则弹出队尾元素,直到队列为空或者当前元素大于等于队尾元素
if (a[i] < a[q[tai]] && hea <= tai)
tai--;
else {
// 否则将当前元素的下标i加入队尾
q[++tai] = i;
break;
}
}
// 检查队头元素是否已超出窗口范围,若是,则弹出队头元素
if (i - q[hea] + 1 > m)
hea++;
// 如果当前下标i大于等于窗口大小m,则说明已经可以输出窗口内的最小值了
if (i >= m)
cout << a[q[hea]] << endl; // 输出窗口内的最小值
}
return 0;
}
deque
#include <iostream>
#include <deque>
#include <vector>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int>arr(n + 1); //用来存数据
deque<int>q; //双端队列,用来存m范围内最小数的下标
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
while (1)
{
if (q.size() && arr[i] < arr[q.back()])q.pop_back();//只有当双端队列里面有数时才能进行比较,如果小于队尾元素,则弹出队尾。
else {
q.push_back(i); //如果队列里面没数了,或者i>队尾元素则直接把该i下标放入队列中
break;
}
}
if (i - q.front() + 1 > m)q.pop_front(); //当队头元素不属于m区间范围了,则弹出队头元素,换下一个队头
if (i >= m)cout << arr[q.front()] << endl; //当进行m次后输出队头元素
}
return 0;
}