Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Your KthLargest
class will have a constructor which accepts an integer k
and an integer array nums
, which contains initial elements from the stream. For each call to the method KthLargest.add
, return the element representing the kth largest element in the stream.
Example:
int k = 3; int[] arr = [4,5,8,2]; KthLargest kthLargest = new KthLargest(3, arr); kthLargest.add(3); // returns 4 kthLargest.add(5); // returns 5 kthLargest.add(10); // returns 5 kthLargest.add(9); // returns 8 kthLargest.add(4); // returns 8
Note:
You may assume that nums
' length ≥ k-1
and k
≥ 1.
利用小顶堆解决,即优先队列,时间复杂度为O(logk)
1 class KthLargest {//优先队列 堆 mytip 2 3 PriorityQueue<Integer> heap; 4 int k; 5 6 public KthLargest(int k, int[] nums) { 7 heap = new PriorityQueue<Integer>(k); 8 this.k =k; 9 for (int x:nums) { 10 this.add(x); 11 } 12 13 } 14 15 public int add(int val) { 16 if(heap.size()<k){ 17 heap.add(val); 18 } 19 else if(val>heap.peek()){ 20 heap.poll(); 21 heap.add(val); 22 } 23 return heap.peek(); 24 } 25 }
使用通常二分查找,找到数据需保存的位置,添加后返回第k个值,二分查找时间复杂度为O(logn)(可优化为O(logk)),ArrayList指定位置插入时间复杂度为O(n),故时间复杂度为O(n)。
1 class KthLargest {//二分查找 my 2 3 List<Integer> topk ; 4 int k; 5 6 public KthLargest(int k, int[] nums) { 7 topk= new ArrayList<Integer>(); 8 this.k =k; 9 for (int x:nums) { 10 this.add(x); 11 } 12 13 } 14 15 public int add(int val) { 16 int pos= this.getPos(val,0,topk.size()); 17 this.topk.add(pos,val); 18 if(topk.size()<=this.k){ 19 return topk.get(topk.size()-1); 20 } 21 else{ 22 return topk.get(k-1); 23 } 24 } 25 private int getPos(int val,int start,int end){ 26 if(start>=end){ 27 return start; 28 } 29 int mid =(start+end)/2; 30 if(this.topk.get(mid)<val){ 31 return getPos(val,start,mid); 32 } 33 else { 34 return getPos(val,mid+1,end); 35 } 36 } 37 }