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));
}
}