滑动窗口(入门题)

思路:

1.考虑普通队列:复杂度O(n*k);

2.注意到在探讨最小值时,

  1. 当新元素入队时,可以删掉比它大的数,然后再入队,即保证单调递增队列,这样入队复杂度依旧O(n),查询复杂度为O(1),总体O(n)
  2. 当队头元素出队时,要保证下标小于窗口最小下标时入队,于是考虑队列里存下标,通过a[]函数映射求取下标所对应的值,当下标不满足条件就出队
  3. 考虑用i描述窗口尾巴下标,这样逐一元素按规则进入单调队列,当i即窗口尾>=k-1时,按题意输出队头元素即最小值

3.探讨最大值,改成单调递减的单调队列,即删除所有小于等于它的数,出队条件不变,仍是下标小于窗口最小下标

代码:

#include

using namespace std;

const int N = 1e6 + 10;
int a[N],q[N];

int hh = 0,tt = -1;
int main()
{
    int n,k;
    cin >> n >> k;
    
    for(int i = 0;i < n;i ++)
    {
        cin >> a[i];
    }
    
    for(int i = 0;i < n;i ++)
    {
        if(q[hh] < i - k + 1)hh ++;
        while(hh <= tt && a[q[tt]] >= a[i])tt --;
        q[++ tt] = i;
        
        if(i >= k - 1)cout <= k - 1)cout <

你可能感兴趣的:(算法)