堆排序用於求解 TopK Elements 問題,通過維護一個大小爲 K 的堆,堆中的元素就是 TopK Elements。當然它也可以用於求解 Kth Element 問題,因爲最後出堆的那個元素就是 Kth Element。
快速選擇也可以求解 TopK Elements 問題,因爲找到 Kth Element 之後,再遍歷一次數組,所有小於等於 Kth Element 的元素都是 TopK Elements。
Leetocde : 215. Kth Largest Element in an Array
解法1:可以直接用Arrays.sort()進行排序(默認升序),然後返回就好。 時間複雜度 O(NlogN),空間複雜度 O(1) 。
解法2:堆排序,Java中PriorityQueue優先隊列實現最小堆。
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int val : nums) {
pq.add(val);
if (pq.size() > k) {
pq.poll();
}
}
return pq.peek();
}
解法3:快排
class Solution {
public int findKthLargest(int[] nums, int k) {
int left=0,right=nums.length-1;
while(true){
int pos=partition(nums,left,right);
if(pos==k-1) return nums[pos];
if(pos>k-1) right=pos-1;
else left=pos+1;
}
}
public int partition(int []nums,int left,int right){
int pivot=nums[left],l=left+1,r=right;
while(l<=r){
if(nums[l]<pivot&&nums[r]>pivot){
swap(nums,l,r);
}
if(nums[l]>=pivot) ++l;
if(nums[r]<=pivot) --r;
}
swap(nums,left,r);
return r;
}
public void swap(int[] nums,int a,int b){
int tmp=nums[a];
nums[a]=nums[b];
nums[b]=tmp;
}
}
Leetocde :703. Kth Largest Element in a Stream
這題跟Kth Largest Element in an Array類似,不同的是,那題數組是確定的,不會增加元素,因此Kth Largest Element也是確定的,這題數組在變大,Kth Largest Element也在不停的變化。但我們只關心前K大個數,所以可以用最小堆來保存前K個數字。