239. Sliding Window Maximum (滑动窗口最大值, 大根堆or 单调队列)

You are given an array of integers 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.

Return the max sliding window.

Example 1:

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation: 
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

 法1:

 1 class Solution {
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
 4         vector<int> res;
 5         priority_queue<pair<int, int>> q;
 6         for(int i = 0; i < k;++i) {
 7             q.push({nums[i],i});
 8         }
 9         res.push_back(q.top().first);
10 
11         for(int i = k;i < nums.size();++i) {
12             q.push({nums[i],i});
13             while(q.top().second + k <= i) {
14                 q.pop();
15             }
16             res.push_back(q.top().first);
17         }
18         return res;
19     }
20 };

法二:

https://labuladong.gitbook.io/algo/mu-lu-ye-1/mu-lu-ye-2/dan-tiao-dui-lie

首先,明确一个概念,单调队列是在队列中所有的元素都是单调的,要么单调增,要么单调减,新增元素时到队尾,此时队列不符合单调性就将队尾元素出队,直到队列单调或空。

 1 class MonotonicQueue {
 2 private:
 3     deque<int> data;
 4 public:
 5     void push(int n) {
 6         while (!data.empty() && data.back() < n) 
 7             data.pop_back();
 8         data.push_back(n);
 9     }
10     
11     int max() { return data.front(); }
12     
13     void pop(int n) {
14         if (!data.empty() && data.front() == n)
15             data.pop_front();
16     }
17 };
18 
19 class Solution {
20 public:
21     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
22     MonotonicQueue window;
23     vector<int> res;
24     for (int i = 0; i < nums.size(); i++) {
25         if (i < k - 1) { //先填满窗口的前 k - 1
26             window.push(nums[i]);
27         } else { // 窗口向前滑动
28             window.push(nums[i]);
29             res.push_back(window.max());
30             window.pop(nums[i - k + 1]);
31         }
32     }
33     return res;
34     }
35 };
 1 class Solution {
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
 4     deque<int> q;
 5     vector<int> res;
 6     for (int i = 0; i < nums.size(); i++) {
 7         // push
 8         while(!q.empty()&& q.back() < nums[i]) {
 9             q.pop_back();
10         }
11         q.push_back(nums[i]);
12         if (i >= k - 1) { //前k - 1 已经填满
13             res.push_back(q.front());
14             // pop
15             if(!q.empty() && nums[i - k + 1]== q.front()) {
16                 q.pop_front();
17             }
18         }
19     }
20     return res;
21     }
22 };
原文地址:https://www.cnblogs.com/zle1992/p/14801627.html