• 单调队列


    单调队列是一种操作受限的数据结构

    只允许从队首出队、队首和队尾入队。

    它可以用于维护区间内的最大值和最小值。

    性质:

    1.单调队列内的所有元素的相对位置和原列表中相同。

    2.队首的元素根据需要,一定是最大(或最小的)。

    3.队首的元素一定是最先入队的,队尾的元素是走后入队的。

    4.队列中的元素保持着单调性。

    看一道模版题:

    https://www.luogu.com.cn/problem/P1886

    代码如下,注释解释了各个操作的意义。

     1 #include <queue>
     2 #include <vector>
     3 #include <iostream>
     4 using namespace std;
     5 struct node{
     6     int id;
     7     int data;
     8 };
     9 deque<node> max_dq;
    10 deque<node> min_dq;
    11 vector<int> max_ans;
    12 vector<int> min_ans;
    13 int main(){
    14     int n,k,temp;
    15     cin >> n >> k;
    16     for(int i = 1; i <= n; i++){
    17         cin >> temp;
    18         while(not max_dq.empty() and max_dq.back().data < temp){
    19             max_dq.pop_back();
    20         }
    21         
    22         while(not min_dq.empty() and min_dq.back().data > temp){
    23             min_dq.pop_back();
    24         }
    25         /*
    26          * 以最大值为例进行说明 :
    27          * 单调队列维护区间最大值
    28          * 队首元素最大
    29          * 当新加入一个元素时,进行两个判断 :
    30          *
    31          * 1. while(队尾的元素比新元素的data小: pop_front()) , 这是因为 , 由于后入队的元
    32          *    素必定比先入队的元素晚进入我们的滑动窗口,同时呢, 这个元素又比当前队尾的元素的值大
    33          *    那么, 当前队尾的元素有生之年(luogu某题解里的奇妙词汇,感觉用的好恰当哈哈哈)不可
    34          *    能成为最大值了,直接出队。
    35          *
    36          * 2. while(队首的元素与新元素的id相差超过了maxsize :pop_back())
    37          *    这是因为, 由于区间的大小是有限的, 当两个元素的 id 相差超过了区
    38          *    间长度时,队首元素需要出队然后将新元素 push_back()
    39          *
    40          * 当第 k 个元素入队后,开始打印元素
    41          */
    42         while(not max_dq.empty() and i - max_dq.front().id >= k){
    43             max_dq.pop_front();
    44         }
    45         
    46         while(not min_dq.empty() and i - min_dq.front().id >= k){
    47             min_dq.pop_front();
    48         }
    49         
    50         node New;
    51         New.id = i; New.data = temp;
    52         max_dq.push_back(New);
    53         min_dq.push_back(New);
    54         if(i >= k){
    55             max_ans.push_back(max_dq.front().data);
    56             min_ans.push_back(min_dq.front().data);
    57         }
    58     }
    59     int first = 1;
    60     for(auto it = min_ans.begin(); it not_eq min_ans.end(); it++){
    61         if(first)first = 0;else cout<<" ";
    62         cout<<*it;
    63     }
    64     first = 1;cout<<endl;
    65     for(auto it = max_ans.begin(); it not_eq max_ans.end(); it++){
    66         if(first)first = 0;else cout<<" ";
    67         cout<<*it;
    68     }
    69     return 0;
    70 }
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    [LeetCode] Remove Duplicates from Sorted List
    [LeetCode] Substring with Concatenation of All Words
    [LeetCode] Partition List
    [LeetCode] Reverse Nodes in kGroup
    [LeetCode] Remove Duplicates from Sorted List II
    [LeetCode] Reverse Linked List II
    [LeetCode] Text Justification
    [LeetCode] Swap Nodes in Pairs
    (转)介绍下Nuget在传统Asp.net项目中的使用
    Entity Framework中的Migrations
  • 原文地址:https://www.cnblogs.com/popodynasty/p/12198405.html
Copyright © 2020-2023  润新知