文章目录
【一】 Priority Queue(优先队列)- 正常入,按优先级出
- 实现机制1: Heap(Binary,Binomial,Fibonacci)
![](https://i-blog.csdnimg.cn/blog_migrate/0d401a84e29e0b3f9f7353aa14aed96f.png)
- 实现机制2: Binary Search Tree(二叉搜索树)
【二】 Mini Heap(小顶堆)- 父亲节点 < 左右孩子节点
![](https://i-blog.csdnimg.cn/blog_migrate/785a8b57a2e0622d3f453effff45157c.png)
【三】 Max Heap(大顶堆)- 父亲节点 > 左右孩子节点
![](https://i-blog.csdnimg.cn/blog_migrate/689b890312fb1cfe6d9c8a7c66c9ee01.png)
【四】 Interview(面试题)
【4.1】 LeetCode 703:Kth Largest Element in a Stream(数据流中的第K大元素)
// c++( priority_queue,优先队列 )
class KthLargest {
public:
KthLargest(int k, vector<int>& nums) {
// 遍历 nums
for(int num : nums){
q.push(num);
if(q.size() > k) q.pop();
}
K = k;
}
int add(int val) {
q.push(val);
if(q.size() > K) q.pop();
return q.top();
}
private:
// c++优先队列容器,实现了最小堆,每次进行操作均会自动排序
priority_queue<int, vector<int>, greater<int>> q;
int K; // 用于 add 操作中传值判断
};
【4.2】 LeetCode 239:Sliding Window Maximum(滑动窗口最大值)
# python(直接用数组实现双向队列)
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
# 如果传进来的 nums 为空,则返回空 list
if not nums: return []
window, res = [], []
# i 是索引,即元素下标,x 是元素本身
for i, x in enumerate(nums):
# 窗口大小为k,判断是否需要将队列前排元素弹出
if window and window[0] <= i-k:
window.pop(0)
# 弹出 比准备进来的元素小的 数的下标
while window and nums[window[-1]] <= x:
window.pop()
# 将元素下标加入数组
window.append(i)
# 存储 nums[队列最前面的下标]
if i >= k-1:
res.append(nums[window[0]])
return res
// c++( deque,双向队列 )
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
// if(nums.empty()) return 0; 无法执行该语句
vector<int> res; // 数组容器
deque<int> window; // 双向队列容器,存储数组元素的下标
// 遍历数组
for(int i = 0; i < nums.size(); i++) {
// 当 双向队列的第一个值(下标) == i-k 时,出队列,维持大小为 k 的窗口
if(!window.empty() && window.front() == i-k) window.pop_front();
// 当 新传进来的值 >= nums[队列末尾的值],出队列
while(!window.empty() && nums[window.back()] <= nums[i]) window.pop_back();
// 将元素下标压进队列
window.push_back(i);
// 最大的元素的下标,始终在队列的最前面,存进数组里
if(i >= k-1) res.push_back(nums[window.front()]);
}
return res;
}
};