问题
在未排序的数组中找到第 k 个最大的元素
例子
思路
第k大,即下标为nums.length-k【第一大为len-1】
- 暴力:先排序,然后返回nums.length-k下标
- 使用快排,如果pivot_index是len-k的话就停止
- 使用堆。
1:堆排序,从第1大开始,找到第k大,就停止
2:小顶堆(维持k个结点),然后不断把数组中的数字取出,如果大于最小的,替换掉最小的,最终小顶堆的根节点就是k大
代码
//暴力:
Arrays.sort(nums);
return nums[nums.length-k];
//快排
public int findKthLargest(int[] nums, int k) {
//第k大的坐标为nums.length-k
int low = 0, high=nums.length-1;
while (low<high){
int pivot_index = partition(nums,low,high);
if (pivot_index==nums.length-k) break;
if (pivot_index<nums.length-k) low=pivot_index+1;
if (pivot_index>nums.length-k) high = pivot_index-1;
}
return nums[nums.length-k];
}
public void quick_sort(int[] nums,int low, int high,int k) {
if (low>=high) return ;
int pivot_index = partition(nums,low,high);
if (pivot_index==nums.length-k) {
return;
}
quick_sort(nums,low,pivot_index-1,k);
quick_sort(nums,pivot_index+1,high,k);
}
public int partition(int[] nums, int low, int high) {
int pivot_index = low;
int pivot=nums[low];
while (low<high) {
while (low<high && nums[high]>=pivot) high--;
while (low<high && nums[low]<=pivot) low++;
if (low<high) {
int temp = nums[high];
nums[high]=nums[low];
nums[low]=temp;
}
}
if (pivot_index!=high) {
int temp = pivot;
nums[pivot_index]=nums[high];
nums[high]=temp;
}
return high;
}
}
//堆
public int findKthLargest(int[] nums, int k) {
heap_sort(nums,k);
return nums[nums.length-k];
}
public void heapify(int[] nums, int n, int i) {
if (2*i+1>n-1) return ;
int L = 2*i+1, R = 2*i+2;
int max_index = i;
max_index = nums[L]<=nums[max_index]?max_index:L;
if (R<=n-1) {
max_index = nums[R]<=nums[max_index]?max_index:R;
}
if (max_index!=i) {
int temp = nums[max_index];
nums[max_index]=nums[i];
nums[i]=temp;
heapify(nums,n,max_index);
}
}
public void build_heapify(int[] nums) {
int last_index = nums.length-1;
int last_father = (last_index-1)/2;
for (int i=last_father; i>=0; i--) {
heapify(nums,nums.length,i);
}
}
public void heap_sort(int[] nums,int k) {
build_heapify(nums);
for(int i=nums.length-1; i>=0; i--) {
int temp = nums[0];
nums[0]=nums[i];
nums[i]=temp;
System.out.println(Arrays.toString(nums));
if (k==nums.length-i) return;
heapify(nums,i,0);
}
}
}
//小顶堆
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int i=0; i<nums.length; i++) {
if (pq.size()<k) {
pq.offer(nums[i]);
}else {
if (nums[i]>pq.peek()) {
pq.poll();//将最小的拉出
pq.offer(nums[i]);
}
}
}
return pq.peek();
}