单调队列+滑动窗口
[TOC]
- 模板
代码:
#include<iostream> //https://www.luogu.com.cn/problem/P1886
using namespace std; //双向单调队列
const int maxn=1000005;
int a[maxn],q[maxn],p[maxn],head=1,tail=0; //head,tail:相对的头和尾
int n,k;
void monotone_min(){ //单调递增(q[head]最小)
head=1,tail=0; //head=1,tail=0
for(int i=1;i<=n;i++){
while(head<=tail&&q[tail]>a[i]){ //q[tail]>a[i](不满足的筛选掉)
tail--; //队尾出队
}
q[++tail]=a[i]; //入队
p[tail]=i; //记录当前队尾索引
if(p[head]<=i-k){ //超出滑动窗口(例:[-3,3,6])
head++; //队首出队
}
if(i>=k){ //满足滑动窗口条件(从第一个窗口往后,每移动一位,输出一个元素)
cout<<q[head]<<" "; //输出最小元素(队首)
}
}
cout<<endl;
}
void monotone_max(){ //单调递减(q[head]最大)
head=1,tail=0;
for(int i=1;i<=n;i++){
while(head<=tail&&q[tail]<a[i]){ //q[tail]<a[i]
tail--;
}
q[++tail]=a[i];
p[tail]=i;
if(p[head]<=i-k){
head++;
}
if(i>=k){
cout<<q[head]<<" ";
}
}
cout<<endl;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
monotone_min();
monotone_max();
return 0;
}
/*
8 3
1 3 -1 -3 5 3 6 7
-1 -3 -3 -3 3 3
3 3 5 5 6 7
*/
题
luoguP1440
#include<iostream>
using namespace std;
const int N=2000005;
int q[N],p[N],n,m,x;
int main(){
// ios::sync_with_stdio(0);
// cin.tie(0);
cin>>n>>m;
// cout<<0<<endl;
printf("0\n");
// for(int i=1;i<=n;i++){
// // cin>>a[i];
// scanf("%d",&a[i]);
// }
int head=1,tail=0;
for(int i=1;i<=n-1;i++){
scanf("%d",&x);
while(head<=tail&&q[tail]>x){
tail--;
}
q[++tail]=x;
p[tail]=i;
if(p[head]<=i-m){
head++;
}
// cout<<q[head]<<endl;
printf("%d\n",q[head]); //需使用printf()才不会TLE
}
// cin>>x;
scanf("%d",&x);
return 0;
}
/*
6 2
7 8 1 4 3 2
0
7
7
1
1
3
*/
LC 5402. 绝对差不超过限制的最长连续子数组
class Solution {
public:
int longestSubarray(vector<int>& nums, int limit) {
multiset<int> s; //可重复set
int n=nums.size();
int i=0;
int ans=0;
for(int j=0;j<n;++j){
s.insert(nums[j]);
while(*s.rbegin()-*s.begin()>limit){ //set自动排序,无需求绝对值
s.erase(s.find(nums[i])); //删除队首元素
i++; //头指针后移
}//(因为是任意两元素不满足情况,所以后序无需判断)
ans=max(ans,j-i+1); //头尾指针求队的长度
}
return ans;
}
};
LC1423. 可获得的最大点数
class Solution { //滑动窗口
public:
int maxScore(vector<int>& cardPoints, int k) {
int n=cardPoints.size();
int sum=0,s=0; //sum:n-k个数的和(滑动窗口) s:所有总和
for(int i=0;i<n;++i){
s+=cardPoints[i];
if(i<n-k)
sum+=cardPoints[i]; //sum:尾部留k个空间
}
int ans=sum; //ans=sum
for(int i=0,j=n-k;j<n;++i,++j){ //j<n
sum=sum-cardPoints[i]+cardPoints[j];
ans=min(ans,sum); //滑动窗口和最小(剩余值最大,逆向思维:找最大子数组和)
}
return s-ans; //最后再减:可能取所有元素导致n-k=0 => sum=0
}
};
results matching ""
No results matching ""
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"单调队列(滑动窗口)","level":"1.6","depth":1,"next":{"title":"单调栈","level":"1.7","depth":1,"path":"单调栈.md","ref":"单调栈.md","articles":[]},"previous":{"title":"大数","level":"1.5","depth":1,"path":"大数.md","ref":"大数.md","articles":[]},"dir":"ltr"},"config":{"gitbook":"*","theme":"default","variables":{},"plugins":["-lunr","livereload"],"pluginsConfig":{"livereload":{},"highlight":{},"search":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"}},"file":{"path":"单调队列(滑动窗口).md","mtime":"2020-08-26T07:39:32.103Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2020-08-26T07:48:08.575Z"},"basePath":".","book":{"language":""}});
});
一键复制
编辑
Web IDE
原始数据
按行查看
历史