目录
leetcode215题.数组中的第k个最大元素
leetcode347题.前k个高频元素
leetcode295题.数据流的中位数
对优先队列感兴趣的朋友可以去看我上一篇文章。
优先队列基础讲解-CSDN博客
215. 数组中的第K个最大元素 - 力扣(LeetCode)
给定整数数组
nums
和整数k
,请返回数组中第**k**
个最大的元素。请注意,你需要找的是数组排序后的第
k
个最大的元素,而不是第k
个不同的元素。你必须设计并实现时间复杂度为
O(n)
的算法解决此问题。示例 1:
输入: [3,2,1,5,6,4], k = 2 输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4 输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
class Solution {
public int findKthLargest(int[] nums, int k) {
// 默认是小根堆 复杂度 空间:O(k). 时间 nlogk
Queue minQueue = new PriorityQueue<>();
for(int i = 0 ; i < nums.length; i++){
if(minQueue.size() < k){
minQueue.offer(nums[i]);
}else if(minQueue.peek() < nums[i]){
minQueue.poll();
minQueue.offer(nums[i]);
}
}
return minQueue.peek();
}
}
347. 前 K 个高频元素 - 力扣(LeetCode)
给你一个整数数组
nums
和一个整数k
,请你返回其中出现频率前k
高的元素。你可以按 任意顺序 返回答案。示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
提示:
1 <= nums.length <= 105
k
的取值范围是[1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前
k
个高频元素的集合是唯一的
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 创建一个HashMap用于存储数字及其出现的频率
Map map = new HashMap<>();
// 遍历输入数组,统计每个数字出现的次数
for(int num:nums){
map.put(num,map.getOrDefault(num,0)+1);
}
// 创建一个优先队列(最小堆),用于存储频率最高的k个数字
PriorityQueue queue = new PriorityQueue<>(new Comparator(){
public int compare(Integer a,Integer b){
// 比较两个数字的频率,频率高的排在前面
return map.get(a) - map.get(b);
}
});
// 遍历HashMap的键集,将前k个频率最高的数字添加到优先队列中
for(Integer key:map.keySet()){
if(queue.size() < k){
queue.add(key);
}else if(map.get(key) > map.get(queue.peek())){
// 如果当前数字的频率大于优先队列中的最小频率,则替换最小频率的数字
queue.poll();
queue.add(key);
}
}
// 创建一个长度为k的数组,用于存储结果
int [] res = new int[k];
int index = 0;
// 从优先队列中依次取出元素,将其添加到结果数组中
while(!queue.isEmpty()){
res[index++] = queue.poll();
}
// 返回结果数组
return res;
}
}
295. 数据流的中位数 - 力扣(LeetCode)
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
- 例如
arr = [2,3,4]
的中位数是3
。- 例如
arr = [2,3]
的中位数是(2 + 3) / 2 = 2.5
。实现 MedianFinder 类:
MedianFinder()
初始化MedianFinder
对象。void addNum(int num)
将数据流中的整数num
添加到数据结构中。double findMedian()
返回到目前为止所有元素的中位数。与实际答案相差10-5
以内的答案将被接受。示例 1:
输入 ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [[], [1], [2], [], [3], []] 输出 [null, null, null, 1.5, null, 2.0] 解释 MedianFinder medianFinder = new MedianFinder(); medianFinder.addNum(1); // arr = [1] medianFinder.addNum(2); // arr = [1, 2] medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2) medianFinder.addNum(3); // arr[1, 2, 3] medianFinder.findMedian(); // return 2.0
提示:
-105 <= num <= 105
- 在调用
findMedian
之前,数据结构中至少有一个元素- 最多
5 * 104
次调用addNum
和findMedian
class MedianFinder {
//
Queue max;// 保存较小那部分,并且多保存一个
Queue min;// 保存较大那部分
public MedianFinder() {
max = new PriorityQueue<>((x,y)->(y - x));
min = new PriorityQueue<>();
}
public void addNum(int num) {
// 偶数
if(max.size() == min.size()){
min.offer(num);
max.offer(min.poll());
} else {
max.offer(num);
min.offer(max.poll());
}
}
public double findMedian() {
int size = max.size() + min.size();
if(size % 2 == 1){
return max.peek() * 1.0;
}else{
return (max.peek() + min.peek()) / 2.0;
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/