当使用Priority Queue排序找出第K个最大的对象时,一般做法是将对象按从大到小排列在队列里,然后pop out K个。这个做法的时间复杂度是O(NlogN)。
//time: O(NlogN) space: O(N)
public int findKthLargestMaxHeap(int[] nums, int k) {
//large number first
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>((n1, n2) -> -1*(n1 - n2));
for(int i: nums) {
maxHeap.add(i);
}
while(k>1) {
maxHeap.poll();
k--;
}
return maxHeap.poll();
}
如果我们想要更有效率,其实可以将对象在队列里从小到大排列,并控制队列长度永远为K。当队列长度超过K时,推出队列头部最小的值,保证队列中的值永远是K个到目前为止的最大值。
这样做的话,因为队列长度永远是K,所以每次插入Priority Queue的时间复杂度是O(logK),故处理完所有数据时间复杂度为O(NlogK)。
返回的时候只要取队列头部的值就行了。
//time: O(NlogK) space: O(K)
public int findKthLargestMinHeap(int[] nums, int k) {
//small number first
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
for(int i: nums) {
minHeap.add(i);
if (minHeap.size()>k) {
minHeap.poll();
}
}
return minHeap.poll();
}
网友评论