什么是优先队列
优先队列也是一种队列,只不过不同的是,优先队列的出队顺序是按照优先级来的。
优先队列(ADT, Abstract Data Type)是一种数据结构, 支持插入和删除最小/大值操作(返回并删除最小/大元素)。
对于最小健值元素拥有最高的优先队列, 称之为升序优先队列。
同理, 对于最大健值元素拥有最高的优先队列,称之为降序优先队列。
解决什么问题
需要找到元素集合中的最小或最大元素。
优先队列ADT操作
主要操作
- 插入
- 删除
- 获取
辅助操作
- 第k小/大
- 大小
- 堆排列
优先队列的应用
- 数据压缩:赫夫曼编码算法
- 最短路径算法:Dijkstra算法
- 最小生成树算法:Prim算法
- 事件驱动仿真:顾客排队算法
- 选择问题:查找第k个最小元素 拜托,面试别再问我TopK了!!!
练习题集合
- 剑指 Offer II 059. 数据流的第 K 大数值
- 703. 数据流中的第 K 大元素
- 剑指 Offer 40. 最小的k个数
- 1337. 矩阵中战斗力最弱的 K 行
- 1464. 数组中两元素的最大乘积
- 2099. 找到和最大的长度为 K 的子序列
- LCP 33. 蓄水
- 1046. 最后一块石头的重量
- 506. 相对名次
- 1834. 单线程 CPU
堆(大根堆/小根堆)
大根堆:父节点的值比每一个子节点的值都要大。
同理, 小根堆:父节点的值比每一个子节点的值都要小。
class MinHeap {constructor(data = []) {this.data = data;this.comparator = (a, b) => a - b;this.heapify();}// 堆化heapify() {if (this.size() < 2) return;for (let i = 1; i < this.size(); i++) {this.bubbleUp(i);}}peek() {if (this.size() === 0) return null;return this.data[0];}offer(value) {this.data.push(value);this.bubbleUp(this.size() - 1);}poll() {if (this.size() === 0) {return null;}const result = this.data[0];const last = this.data.pop();if (this.size() !== 0) {this.data[0] = last;this.bubbleDown(0);}return result;}bubbleUp(index) {while (index > 0) {const parentIndex = (index - 1) >> 1;if (this.comparator(this.data[index], this.data[parentIndex]) < 0) {this.swap(index, parentIndex);index = parentIndex;} else {break;}}}bubbleDown(index) {const lastIndex = this.size() - 1;while (true) {const leftIndex = index * 2 + 1;const rightIndex = index * 2 + 2;let findIndex = index;if (leftIndex <= lastIndex &&this.comparator(this.data[leftIndex], this.data[findIndex]) < 0) {findIndex = leftIndex;}if (rightIndex <= lastIndex &&this.comparator(this.data[rightIndex], this.data[findIndex]) < 0) {findIndex = rightIndex;}if (index !== findIndex) {this.swap(index, findIndex);index = findIndex;} else {break;}}}swap(index1, index2) {[this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]];}size() {return this.data.length;}}
第k个最小元素
var KthLargest = function(k, nums) {
this.k = k;
this.heap = new MinHeap();
for (let num of nums) {
this.add(num);
}
};
KthLargest.prototype.add = function(val) {
this.heap.offer(val);
if (this.heap.size() > this.k) {
this.heap.poll();
}
return this.heap.peek();
};
