1. 程式人生 > 實用技巧 >單調佇列 Monotonic Queue應用:leetcode(未完待續)

單調佇列 Monotonic Queue應用:leetcode(未完待續)

239.Sliding Window Maximum

581:https://leetcode.com/problems/shortest-unsorted-continuous-subarray/

862:https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/
496:https://leetcode.com/problems/next-greater-element-i/
84:https://leetcode.com/problems/largest-rectangle-in-histogram/

239:最主要是push

class Solution {
public: //單調佇列:單調遞增或單調遞減佇列 class MQ { deque<pair<int,int>> mq; //first為陣列下標。second為push該數時前面remove掉的數的個數(保持MQ中第一個元素為最大值,可能會pop掉之前的好幾個元素) //那麼,每次在front_pop時,second為0,才會pop該元素,否則,second-1(其實可以理解second為佇列中總的元素數) public: void push(int val){
//如果為空佇列,直接push if(mq.empty()){ mq.push_back(make_pair(val,0)); return ; } //雙端佇列不為空,remove掉前面小於該val的數,保證最大的為隊頭. //而且保證佇列中為遞減,只保留最大、次大。。。 //3 1 在佇列,現在push 2: 如何做? int cnt = 0
; while(!mq.empty() && mq.back().first < val){ cnt = cnt + mq.back().second+1; mq.pop_back(); } mq.push_back(make_pair(val,cnt)); } //pop的時候,pop隊頭,但是要保證隊頭元素的second屬性為0. void pop(){ if(!mq.empty() && mq.front().second){ mq.front().second--; return ; } if(!mq.empty()) mq.pop_front(); } int getMax(){ return mq.front().first; } }; vector<int> maxSlidingWindow(vector<int>& nums, int k) { //每一次push,getMax,pop int n = nums.size(); vector<int> res; deque<pair<int,int>> dq; MQ mq; for(int i=0;i<n;i++){ mq.push(nums[i]); if(i >= k-1){ res.push_back(mq.getMax()); mq.pop(); } } return res; } };

class Solution {
public:
    //mq存nums陣列下標
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> mq;
        vector<int> res;
        int n = nums.size();
        for(int i=0;i<n;i++){
            if(!mq.empty() && i-mq.front() >=k) mq.pop_front();
            //push進去
            while(!mq.empty() && nums[mq.back()] < nums[i]){
                mq.pop_back();
            }
            mq.push_back(i);
            if(i >= k-1) res.push_back(nums[mq.front()]);
        }
        return res;
    }
};