1.题目描述:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
2.解题思路及代码:
方法一:
采用与快速排序相似的方法,选择一个随机的基准值,将基准值划分到正确的位置(比它小的在左,比它大的在右),如果k恰好等于基准值的下标,则返回基准值,若小于则递归调用,找左半边,若大于则找右半边
代码如下:
class Solution { private int[] nums; public void swap(int a,int b){ int tmp=nums[a]; nums[a]=nums[b]; nums[b]=tmp; } public int partition(int left,int right,int pivot_index){ swap(left,pivot_index); int tmp=nums[left]; int i=left; int j=right+1; while(true){ while(nums[++i]<tmp&&i<right); while(nums[--j]>tmp); if(i>=j) break; swap(i,j); } nums[left]=nums[j]; nums[j]=tmp; return j; } public int randomizedSelect(int left,int right,int k){ if(left==right) return nums[left]; Random rd=new Random(); int pivot_index=left+rd.nextInt(right-left); pivot_index=partition(left,right,pivot_index); if(k==pivot_index) return nums[k]; else if(k<pivot_index) return randomizedSelect(left,pivot_index-1,k); return randomizedSelect(pivot_index+1,right,k); } public int findKthLargest(int[] nums, int k) { this.nums=nums; return randomizedSelect(0,nums.length-1,nums.length-k); } }
方法二:
采用优先队列存放前K个最大元素,返回堆顶即可
class Solution { public int findKthLargest(int[] nums, int k) { PriorityQueue<Integer> heap = new PriorityQueue<Integer>((n1, n2) -> n1 - n2); for (int n: nums) { heap.add(n); if (heap.size() > k) heap.poll(); } // output return heap.poll(); } }