html怎么做滑动窗口,单调队列(滑动窗口).html

单调队列(滑动窗口) · GitBook
  • Introduction

  • 并查集

  • 差分

  • 尺取法双指针法

  • 大数

  • 单调队列(滑动窗口)

  • 单调栈

  • 动态规划

  • 二分

  • 分治

  • 哈希表

  • 链表

  • 模拟

  • 排序

  • 前缀和

  • 三指针法

  • 设计

  • 数论

  • 数学

  • 数组

  • 搜索回溯&枚举

  • 拓扑排序

  • 贪心

  • 位运算

  • 优先队列

  • 字符串

  • 最小生成树

  • LeetCode未分类

  • Manacher

  • Offer

  • Ordered Map

  • Published with GitBook

单调队列+滑动窗口

[TOC]

  • 模板
  • img

  • 代码:

    #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>

#include<cstdio> //scanf...,printf...速度快??

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

原始数据

按行查看

历史

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值