当前位置:网站首页>优先队列PriorityQueue (大根堆/小根堆/TopK问题)
优先队列PriorityQueue (大根堆/小根堆/TopK问题)
2022-07-06 09:21:00 【李孛欢】
PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于优先级堆的极大优先级队列。优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。
默认情况下,PriorityQueue是小顶堆,如代码所示
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.offer(1);
queue.offer(2);
queue.offer(3);
queue.offer(4);
queue.offer(5);
queue.offer(6);
while (!queue.isEmpty()){
System.out.print(queue.poll() + " ");
}
}
输出结果:
我们也可以通过以下方式来构造大顶堆:
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2) -> o2 - o1);//降序
queue.offer(1);
queue.offer(2);
queue.offer(3);
queue.offer(4);
queue.offer(5);
queue.offer(6);
while (!queue.isEmpty()){
System.out.print(queue.poll() + " ");
}
}
输出结果:
Top K问题,力扣347和力扣692:
力扣347:给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
代码如下:注意构造小顶堆的时候(o1,o2)-> o1.getValue() - o2.getValue() 不能省略。
public int[] topKFrequent(int[] nums, int k) {
//key为元素值,value为出现频率
HashMap<Integer,Integer> map = new HashMap<>();
PriorityQueue<Map.Entry<Integer, Integer>> queue
= new PriorityQueue<>((o1,o2)-> o1.getValue() - o2.getValue());
int[] res = new int[k];
for (int num : nums) {
map.put(num,map.getOrDefault(num,0) + 1);
}
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
for (Map.Entry<Integer, Integer> entry : entries) {
queue.offer(entry);
if(queue.size() > k){
queue.poll();
}
}
//留下的都是出现频率最高的
for(int i = 0; i < k; i++){
Map.Entry<Integer, Integer> poll = queue.poll();
res[i] = poll.getKey();
}
return res;
力扣692:给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序排序。
示例:
输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。注意,按字母顺序 "i" 在 "love" 之前。
这题比上题难一点,因为当两个单词出现次数一致时还要考虑按字典序排序,其次是答案需要从高到底排序,这里主要体现在优先队列PriorityQueue的构造上。代码如下:
public List<String> topKFrequent(String[] words, int k) {
List<String> res = new ArrayList<>();
//key为元素,value为出现频率
HashMap<String,Integer> map = new HashMap<>();
for (String word : words) {
map.put(word,map.getOrDefault(word,0) + 1);
}
PriorityQueue<Map.Entry<String,Integer>> queue = new PriorityQueue<>(
((o1, o2) -> {
if(o1.getValue() == o2.getValue()){
return o2.getKey().compareTo(o1.getKey());
}
return o1.getValue() - o2.getValue();
})
);
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
queue.offer(entry);
if(queue.size() > k){
queue.poll();
}
}
for(int i = 0; i < k; i++){
res.add(queue.poll().getKey());
}
Collections.reverse(res);
return res;
}
注意o2.getKey().compareTo(o1.getKey())是按字典倒序,为什么要这么做呢,是因为我们这里用到小顶堆,所以每次poll出来的都是最小频率元素,最后需要reverse一下,为了配合这个,所以我们构造优先队列的时候采用字典倒序。
边栏推荐
- List set map queue deque stack
- Design a key value cache to save the results of the most recent Web server queries
- Set container
- TYUT太原理工大学2022数据库题库选择题总结
- 【九阳神功】2017复旦大学应用统计真题+解析
- IPv6 experiment
- 3.输入和输出函数(printf、scanf、getchar和putchar)
- vector
- The latest tank battle 2022 full development notes-1
- Small exercise of library management system
猜你喜欢
随机推荐
FileInputStream和BufferedInputStream的比较
Pit avoidance Guide: Thirteen characteristics of garbage NFT project
The latest tank battle 2022 - Notes on the whole development -2
【九阳神功】2017复旦大学应用统计真题+解析
【话题终结者】
Arduino+ water level sensor +led display + buzzer alarm
Tyut Taiyuan University of technology 2022 "Mao Gai" must be recited
学编程的八大电脑操作,总有一款你不会
4. Binary search
4.30 dynamic memory allocation notes
【九阳神功】2021复旦大学应用统计真题+解析
MPLS experiment
【九阳神功】2020复旦大学应用统计真题+解析
【九阳神功】2022复旦大学应用统计真题+解析
Differences and application scenarios between MySQL index clock B-tree, b+tree and hash indexes
为什么要使用Redis
View UI plus released version 1.3.0, adding space and $imagepreview components
Set container
C language to achieve mine sweeping game (full version)
Questions and answers of "basic experiment" in the first semester of the 22nd academic year of Xi'an University of Electronic Science and technology