import java.util.Arrays; import java.util.Random; public class FindKthLargest { //方法一:直接排序(调库) public int findKthLargest1(int[] nums, int k) { Arrays.sort(nums); return nums[nums.length-k]; } //方法二:基于快排的选择 public int findKthLargest2(int[] nums, int k) { return quickSelect(nums,0,nums.length-1,nums.length-k); } public int quickSelect(int[] nums, int start, int end, int index) { //找到基准pivot位置返回 int position = randomPatition(nums,start,end); //判断当前pivot位置是否为index if(position == index){ return nums[position]; }else { return position>index?quickSelect(nums,start,position-1,index):quickSelect(nums,position+1,end,index); } } //随机分区的方法 public int randomPatition(int[] nums, int start, int end) { Random random = new Random(); int randIndex = start+random.nextInt(end-start+1); swap(nums,start,end); return partition(nums,start,end); } public static int partition(int[] nums, int start, int end) { int pivot = nums[start]; int left = start,right = end; while (left<right){ //左移右指针,找到一个比pivot小的数,填入空位 while (left<right&&nums[right]>=pivot){ right--; } nums[left] = nums[right]; while (left<right&&nums[left]<=pivot){ left++; } nums[right] = nums[left]; } nums[left] = pivot; return left; } private static void swap(int[] nums, int left, int right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } //方法三:基于堆排序的选择 public int findKthLargest(int[] nums, int k) { int n = nums.length; //保存堆的大小,初始就是n int heapSize = n; //1.构建大顶堆 buildMaxHeap(nums,heapSize); //2.执行n-1次删除堆顶元素操作 for (int i = n-1; i >n-k ; i--) { //将堆顶元素交换到当前堆的末尾 swap(nums,0,i); heapSize--; maxHeapify(nums,0,heapSize); } //3.返回当前堆顶元素 return nums[0]; } //定义一个调整成大顶堆的方法 public void maxHeapify(int[] nums, int top, int heapSize) { //定义左右子节点 int left = top*2+1; int right = top*2+2; //保存当前最大元素的索引位置 int largest = top; //比较左右子节点,记录最大元素索引位置 if(right<heapSize&&nums[right]>nums[largest]){ largest = right; } if(left<heapSize&&nums[left]>nums[largest]){ largest = left; } //将最大元素换到堆顶 if(largest!=top){ swap(nums,top,largest); //递归调用,继续下沉 maxHeapify(nums,largest,heapSize); } } //构建大顶堆 public void buildMaxHeap(int[] nums, int heapSize) { for (int i = heapSize/2-1; i >=0 ; i--) { maxHeapify(nums,i,heapSize); } } public static void main(String[] args) { FindKthLargest findKthLargest = new FindKthLargest(); int[] nums = {3,2,3,1,2,4,5,5,6}; // int[] nums = {3,2,1,5,6,4}; int k = 4; System.out.println(findKthLargest.findKthLargest(nums,k)); } }