问题
题目描述
已知一个数组,a[1]~a[n]共n项,问1~k, 2~(k+1), 3~(k+2)……(n-k+1)~n这些区间的最大值分别是多少?
输入:
第1行2个数,n和k,含义如题中所述。(1<=k<=n<=100000)
接下来1行,有n个数,表示a数组。(a[i]<=1000000)
输出:
1行,共(n-k+1)个数,表示每个区间的最大值。
样例:
输入:
8 3
5 9 4 2 6 10 4 1
输出:
9 9 6 10 10 10
数组模拟实现
#include <bits/stdc++.h> using namespace std; int n, k, a[100005]; int q[100005];//q存a数组的下标 int main(){ cin >> n >> k; for(int i=1;i<=n;i++){ cin >> a[i];//输入 } int l=1,r=1; for(int i=1;i<=n;i++){ while(i-k>=q[l]&&l<r)l++;//队首元素不在当前k区间内了 while(l<r&&a[q[r-1]]<a[i])r--;//如果队尾元素小于当前值,则队尾元素不再可能是最大值 q[r++]=i;//加入第i个数 if(i>=k) cout<<a[q[l]]<<' '; } }
stl双端队列
#include <bits/stdc++.h> using namespace std; int n, k, a[100005]; deque<int> q; int main(){ cin >> n >> k; for(int i=1;i<=n;i++){ cin >> a[i];//输入 } for(int i=1;i<=n;i++){ while(!q.empty()&&i-k>=q.front())q.pop_front();//队首元素不在当前k区间内了 while(!q.empty()&&a[i]>a[q.back()])q.pop_back();//如果队尾元素小于当前值,则队尾元素不再可能是最大值 q.push_back(i);//加入第i个数 if(i>=k) cout<<a[q.front()]<<' '; } }