题目:实时判断数据流中的第K大元素
解这道题,适合的数据结构就是小顶堆了。
小顶堆是一个二叉树数据结构,在小顶堆中,根节点最小,其子节点都比自己的父节点大,维护一个大小为K个元素的小顶堆,堆中所有元素就是前k大的元素了。
具体是解法,可以用Java 的 PriorityQueue,名为优先级队列,但是这个队列不是按照先进先出的,而是按照优先级来出队列,并且PriorityQueue默认就是通过二叉小顶堆实现。
因为堆顶元素值是整个堆中最小的,所以每次要放入的数,先和堆顶元素比较,如果小于等于堆顶元素,那么不需要放入堆中,如果大于堆顶元素,那么堆顶元素出队,将这个元素存入PriorityQueue中。
package com.itzhimei.study.algorithm;
import java.util.PriorityQueue;
public class GetKth {
private int k;
final PriorityQueue<Integer> q;
public GetKth(int k) {
this.k = k;
q = new PriorityQueue<>(k);
}
public void addElem(int n) {
if(q.size() < k) {
//没满就直接入队
q.offer(n);
} else if(q.peek() < n) {
//满了则进行比较,如果n大于堆顶元素,则进入优先级队列
q.poll();
q.offer(n);
}
}
public static void main(String[] args) {
GetKth g = new GetKth(5);
int[] nums = {5,3,7,8,2,15,23,55};
for(int n:nums) {
g.addElem(n);
}
System.out.println("第5大的数字是:" + g.q.peek());
}
}
知识点:
小顶堆/大顶堆,能求前k大/小的一组数。
堆的应用:优先级队列–PriorityQueue,能求第K大的数。