【TopK问题】Java PriorityQueue和C++ priority_queue的用法区别


需求:使用优先队列(小根堆或大根堆),解决Top K问题


0 优先队列解决Top K问题的原理

小根堆(Min-heap):父节点的值小于等于子节点的值;根节点的值最小
大根堆(Max-heap):父节点的值大于等于子节点的值;根节点的值最大

优先队列

优先队列:Java中使用容器PriorityQueue表示;C++中使用STL容器priority_queue表示。

Java优先级队列的原理
基于优先级堆的极大优先级队列,每次从队列中取出具有最高优先权的元素。
(1)自然排序:默认小根堆、按字典序升序排列
(2)比较器排序:使用lambda表达式简化比较器。
小根堆e1 - e2大根堆e2 - e1
字典序升序o1.compareTo(o2)字典序降序o2.compareTo(o1)


0.1 解决Top K大的问题

实现方式:维护大小固定为K小根堆:比较器排序设置e1 - e2(小根堆)。

小根堆:小值元素在堆顶,具有最高优先级;大值元素在堆底,具有较低优先级。

①堆大小固定时,插入元素优先更新堆顶的小值元素,以大值元素取代小值元素;
②满足条件后,依次弹出堆顶小值元素并加入结果集,反转结果集即得到Top K大的元素


补充需求:频度相同时,按字典序(升序)输出
实现方式:比较器排序设置字典序降序o2.compare(o1) ,即字典序较高的元素在堆顶,具有较高优先级;字典序较低的元素在堆底,具有较低优先级。

①堆大小固定时,插入元素优先更新堆顶的字典序较高元素
②满足条件时,依次弹出堆顶高字典序元素并加入结果集,反转结果集后即得到低字典序(字典序升序)的元素。


0.2 解决Top K小的问题

实现方式:维护大小固定为K大根堆:比较器排序设置e2 - e1(大根堆)。

大根堆:大值元素在堆顶,具有最高优先级;小值元素在堆底,具有较低优先级。

①堆大小固定时,插入元素优先更新堆顶的大值元素,以小值元素取代大值元素;
②满足条件后,依次弹出堆顶大值元素并加入结果集,反转结果集即得到Top K小的元素

注1:遍历元素的时间复杂度O(n)删除堆顶/弹出堆顶的时间复杂度O(log n),获取结果时建议使用删除堆顶的方式。
注2:反转结果集的API:
Java使用Collections.reverse(res);,需导包import java.util.Collections
C++使用reverse(res.begin(), res.end());,需包含头文件#include <algorithm>


1 Java的优先队列PriorityQueue

参考文章:Leetcode 215 C++题解【superkakayong】

Java的优先队列,默认创建小根堆/小顶堆/最小堆

构造方法
(1)小根堆默认
自然排序(默认升序)
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();

比较器排序(使用lambda表达式实现)
整型升序:PriorityQueue<Integer> minHeap = new PriorityQueue<>( (i1, i2) -> i1 - i2 );
字典序升序:PriorityQueue<String> minHeap = new PriorityQueue<>( (s1, s2) -> s1.compareTo(s2) );

(2)大根堆
比较器排序(使用lambda表达式实现)
整型降序:PriorityQueue<Integer> maxHeap = new PriorityQueue<>( (i1, i2) -> i2 - i1 );
字典序降序:PriorityQueue<String> maxHeap = new PriorityQueue<>( (s1, s2) -> s2.compareTo(s1) );


2 C++的优先队列priority_queue

C++的优先队列,默认创建大根堆/大顶堆/最大堆
模板参数:<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type>>
第1个参数:元素数据类型(不可省略
第2个参数:容器类型(可省略)
第3个参数:排序方式(可省略),可传递类类型

例:泛型类型(指定模板参数类型):priority_queue< type, container, function>;

注:priority_queue的第1个参数不可省略,后两个参数可省略,

(1)小根堆
内建函数对象-关系仿函数greater<T>
升序:priority_queue<T, vector<T>, greater<T>> min_heap;

(2)大根堆默认
内建函数对象-关系仿函数less<T>
priority_queue<T> max_heap;
priority_queue<T, vector<T>, less<T>> max_heap;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值