设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream
输入:
[“KthLargest”, “add”, “add”, “add”, “add”, “add”]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
输出:
[null, 4, 5, 5, 8, 8]
解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4
kthLargest.add(5); // return 5
kthLargest.add(10); // return 5
kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
class KthLargest{ PriorityQueuepq; int k; public KthLargest(int k, int[] nums){ this.k=k;//初始化队列存放的数量 pq=new PriorityQueue ();//初始化队列 for(int x:nums){//逐个添加,只保留前k大的元素,按照升序添加进队列 add(x); } } public int add(int val){ pq.offer(val);//add添加失败会报错,offer只返回false if(pq.size()>k){ pq.poll();//d出队首值 } return pq.peek();//返回队首值 } }
本题使用优先队列非常合适
优先队列PriorityQueue是Queue接口的实现,可以对其中元素进行排序,
可以放基本数据类型的包装类(如:Integer,Long等)或自定义的类
对于基本数据类型的包装器类,优先队列中元素默认排列顺序是升序排列
peek()//返回队首元素
poll()//返回队首元素,队首元素出队列
add()//添加元素
size()//返回队列元素个数
isEmpty()//判断队列是否为空,为空返回true,不空返回false
我们可以使用一个大小为 kk 的优先队列来存储前 kk 大的元素,其中优先队列的队头为队列中最小的元素,也就是第 kk 大的元素。
在单次插入的 *** 作中,我们首先将元素val 加入到优先队列中。如果此时优先队列的大小大于 k,我们需要将优先队列的队头元素d出,以保证优先队列的大小为 k。
优先队列的实现原理就是小顶堆,那我们手动实现一个(多加分啊)
class KthLargest{ int[] heap;//维护小根堆,小于等于堆顶丢弃,否则插入堆顶后调整,把最小的删掉 int size=0; int count=0; public KthLargest(int k,int[] nums){ heap=new int[k]; count=k; for (int i:nums) { add(i); } } public int add(int val){ if(size=0&&heap[(int)Math.ceil(u/2.0)-1]>heap[u]){//有父节点并有调整必要 int p=(int)Math.ceil((u/2.0)-1);//父节点 int temp=heap[u]; heap[u]=heap[p]; heap[p]=temp; u=p;//要调整节点变成了其父节点 } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)