牛客網編程題 有趣的最大值化 雙向隊列deque的使用

在這裏插入圖片描述
https://www.nowcoder.com/question/next?pid=22088954&qid=907533&tid=31827188

題解:

這題沒有給數據範圍。。。好煩
只能自己試數據==
思路:維護一個雙向隊列,隊列記錄的是元素的下標,保證隊列頭一定是當前最大值的下標,我們按順序將元素放進隊列,當放入一個元素時,從隊列尾開始把小於當前值的元素出隊列,因爲當有更大的元素進入時,在其前面較小的元素已經沒用了。當隊列中元素個數大於等於k個時,我們就可以開始記錄最後結果了。

代碼如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<string>
#include<string.h>
#include<map>
#include<vector>
#define MAX 200005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,k,a[MAX];
deque<int> q;
vector<int> res;

int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    scanf("%d",&k);
    for(int i=0;i<n;i++){
        while(!q.empty()&&a[q.back()]<=a[i]){
            //從後面依次彈出隊列中比當前num值小的元素,同時也能保證隊列首元素爲當前窗口最大值下標
            q.pop_back();
        }
        while(!q.empty()&&i-q.front()+1>k){
            //噹噹前窗口移出隊首元素所在的位置,即隊首元素座標對應的num不在窗口中,需要彈出
            q.pop_front();
        }
        q.push_back(i);
        if(i+1>=k){
            res.push_back(a[q.front()]);
        }
    }
    for(int i=0;i<res.size();i++){
        printf("%s%d",i==0?"":" ",res[i]);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章