剑指 Offer II 059. 数据流的第 K 大数值:
题目链接 :剑指 Offer II 059. 数据流的第 K 大数值
题目:
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
思路:
1、优先队列
(1)使用Priority优先队列完成每次数据更新时的自动排序
(2)构建小顶堆并维护其节点数量为K,当到达阈值取出堆顶元素即当前第K大的元素
(3)每次堆内重排只需要O(logn)的时间
2、手写堆
(1)按照小顶堆构建和重构规则进行搭建
AC代码:
- 优先队列
class KthLargest {
PriorityQueue<Integer> p;
int k;
public KthLargest(int k, int[] nums) {
this.k=k;
p=new PriorityQueue<>();
for(int x:nums)
{
add(x);
}
}
public int add(int val) {
p.offer(val);
if(p.size()>k)
{
p.poll();
}
return p.peek();
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/
- 手写堆
class KthLargest {
int[] heap;
int count=0;
int size=0;
public KthLargest(int k, int[] nums) {
heap=new int[k];
count=k;
for(int x:nums)
{
add(x);
}
}
public int add(int val) {
if (size < count) {
heap[size] = val;
up(size);
size++;
}
else if(val>heap[0])
{
heap[0]=val;
down(0);
}
return heap[0];
}
private void down(int u)
{
int t=u;
if(2*u+1<size&&heap[2*u+1]<heap[t])
t=2*u+1;
if(2*u+2<size&&heap[2*u+2]<heap[t])
t=2*u+2;
if(t!=u)
{
int tmp=heap[u];
heap[u]=heap[t];
heap[t]=tmp;
down(t);
}
}
private void up(int u)
{
//当前节点与它的父节点值比较
while((int)(Math.ceil(u/2.0)-1)>=0&&heap[(int)Math.ceil(u/2.0)-1]>heap[u])
{
int p=(int)(Math.ceil(u/2.0)-1);
int tmp=heap[u];
heap[u]=heap[p];
heap[p]=tmp;
u=p;
}
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/