题目:
最大堆+懒删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <vector> #include <queue> #include <unordered_map> using std::vector;using std::priority_queue;using std::unordered_map;class Solution { public : vector<int > maxSlidingWindow (vector<int > &nums, int k) { priority_queue<int > max_heap; unordered_map<int , int > umap; vector<int > ret; int n = nums.size (); for (int i = 0 ; i < k; i++) { max_heap.push (nums[i]); umap[nums[i]]++; } for (int i = 0 ; i <= n - k; i++) { while (!max_heap.empty () && umap[max_heap.top ()] == 0 ) max_heap.pop (); ret.push_back (max_heap.top ()); if (i + k < n) { umap[nums[i]]--; max_heap.push (nums[i + k]); umap[nums[i + k]]++; } } return ret; } };
其实不用umap来实现懒删除,如果大顶堆中存值的同时也把 index 存起来就能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <vector> #include <queue> #include <utility> using std::vector;using std::priority_queue;using std::pair;class Solution { public : vector<int > maxSlidingWindow (vector<int > &nums, int k) { int i, n = nums.size (); priority_queue<pair<int , int > > q; for (i = 0 ; i < k; ++i) q.emplace (nums[i], i); vector<int > ans = { q.top ().first }; for (i = k; i < n; ++i) { q.emplace (nums[i], i); while (q.top ().second <= i - k) q.pop (); ans.push_back (q.top ().first); } return ans; } };
复杂度O(nlogn)
推荐的方法是单调队列:使用的是 单调递减双端队列 (Monotonic Decreasing Deque) 的方法。
deque<int> q:存储的是数组的下标 (index),而不是具体的数值。
这个队列维护了一个性质:队列中的下标对应的数值是单调递减的。即 nums[q[0]] >= nums[q[1]] >= ...。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <vector> #include <queue> using std::vector;using std::deque;class Solution { public : vector<int > maxSlidingWindow (vector<int > &nums, int k) { int n = nums.size (); deque<int > q; for (int i = 0 ; i < k; ++i) { while (!q.empty () && nums[i] >= nums[q.back ()]) q.pop_back (); q.push_back (i); } vector<int > ans = { nums[q.front ()] }; for (int i = k; i < n; ++i) { while (!q.empty () && nums[i] >= nums[q.back ()]) q.pop_back (); q.push_back (i); while (q.front () <= i - k) q.pop_front (); ans.push_back (nums[q.front ()]); } return ans; } };