数据结构基础 之 单调队列

单调队列

单调队列

主要题型

求滑动窗口之中的最大值或最小值

暴力做法

通过两侧循环来遍历数组,第二层循环模拟滑动窗口,通过比较记录最大值(最小值)

int mx = -INF;
for(int i = 0; i < n; i ++ ){
    for(int j = i; j < i + 3; j ++ ){
        mx = max(a[j], mx);
    }
    cout << mx << " ";
}

算法思想

用队列模拟窗口过程,在当前队列之中,如果左侧的数据大于右边的数组,则弹出左边的数据,保证最后得到的为一个严格递增的序列,结果就是队头元素

图解:(例如:1 3 -1 -3 5 3 6 7)
数据结构基础 之 单调队列

题目

题目链接

滑动窗口:https://www.acwing.com/problem/content/156/

AC代码

学代码就上AcWing!!!
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;

int n, k;
int a[N],q[N];

int main()
{
    cin >> n >> k;
    for(int i = 0; i < n; i ++ )
        cin >> a[i];
        
    int hh = 0, tt = -1;
    for(int i = 0; i < n; i ++ )
    {
    	// 队头后移
        if(hh <= tt && i - k + 1 > q[hh]) hh ++;

		// 判断当前的数据和当前尾的数据的大小,最后保证队列为一个单调队列
        while(hh <= tt && a[q[tt]] > a[i]) -- tt;
        
        q[ ++tt ] = i;

		// 保证数据有 k 个以上才可以输出
        if (i + 1 >= k) cout << a[q[hh]] << " ";
    }
    cout << endl;

	// 处理最大值,与最小值相似
    hh = 0, tt = -1;	
    for(int i = 0; i < n; i ++ )
    {
        if(hh <= tt && i - k + 1 > q[hh]) hh ++;
        while(hh <= tt && a[q[tt]] < a[i]) -- tt;
        
        q[ ++tt ] = i;
        if (i + 1 >= k) cout << a[q[hh]] << " ";
    }
    cout << endl;
    
    return 0;
}
上一篇:openwrt 修改系统时间


下一篇:flex4