239. Sliding Window Maximum

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

For example,
Given nums = <code>[1,3,-1,-3,5,3,6,7]</code>, and k = 3.

Window position Max
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

Therefore, return the max sliding window as <code>[3,3,5,5,6,7]</code>.

Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

解題思路

這題受到求滑動(dòng)窗口中位數(shù)的思想啟發(fā),可以使用有效元素概念。使用一個(gè)hash表保存被剔除的無(wú)效元素。然后使用最大堆去求窗口內(nèi)的最大值,只要保證堆頂部的元素一定是有效的就可以了。

代碼

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        unordered_map<int, int> hash; 
        priority_queue<int, vector<int>> heap;
        vector<int> res;
        
        for (int i = 0; i < nums.size(); i++) {
            if (i < k) {
                heap.push(nums[i]);
            } else {
                res.push_back(heap.top());
                heap.push(nums[i]);
                hash[nums[i - k]] ++;
                while (!heap.empty() && hash[heap.top()]) {
                    hash[heap.top()]--;
                    heap.pop();
                }
            }
        }
        if (!heap.empty()) {
            res.push_back(heap.top());
        }
        return res;
    }
};

當(dāng)然,本題還有一種正解,那就是使用單調(diào)棧。單調(diào)棧,顧名思義,就是單調(diào)遞增或者單調(diào)遞減的棧。單調(diào)棧有很多應(yīng)用,我們主要介紹在這里的應(yīng)用。

首先,我們需要明白:

當(dāng)取一個(gè)大小為k的值時(shí),排在k前面的比k小的元素都不可能成為滑動(dòng)窗口中的最大值。

由此,我們可以維護(hù)一個(gè)單調(diào)遞減的單調(diào)棧:

Step1 : 判斷棧底是否需要被彈出(即元素已經(jīng)無(wú)效
Step2 :對(duì)于每一個(gè)進(jìn)棧的元素,去除棧頂每一個(gè)比他小的元素,再將其入棧
Step3 :棧底的元素值即為當(dāng)前窗口的最大值

由于我們的棧比較特殊,需要在棧底和棧頂操作,所以我們使用雙端隊(duì)列來(lái)實(shí)現(xiàn):

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> dq;
        vector<int> ans;
        for (int i=0; i<nums.size(); i++) {
            if (!dq.empty() && dq.front() == i-k) dq.pop_front();
            while (!dq.empty() && nums[dq.back()] < nums[i])
                dq.pop_back();
            dq.push_back(i);
            if (i>=k-1) ans.push_back(nums[dq.front()]);
        }
        return ans;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容