难度中等705
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
方法一:快速排序
快排每一趟会确定枢纽的位置,当partion 的位置为 nums.legth-k 的时候就是我们要查找的倒数第K大的元素
public class TopK_215 {
public int findKthLargest(int[] nums, int k){
if (nums.length ==1)
return nums[0];
int index = nums.length - k ;
return qsort(nums, 0, nums.length-1, index);
}
public int qsort(int[] a,int l,int r,int index) {
int i = partion(a, l, r);
if(i==index)
return a[index];
else if (index < i)
return qsort(a, l, i-1,index);
else
return qsort(a, i+1, r,index);
}
public int partion(int a[],int left,int right) {
Random random= new Random();
//System.out.println(right+"-"+left);
int randIndex = random.nextInt(right-left+1)+left;
//System.out.println(randIndex);
swap(a, randIndex, right);
int pivot = a[right];
int index =left;
for(int i=left;i<right;i++){
if(a[i]<pivot)
swap(a, index++, i);
}
swap(a, index, right);
return index;
}
public void swap(int[] a,int i,int j) {
int t =a[i];
a[i] = a[j];
a[j] =t;
}
public static void main(String[] args) {
TopK_215 a = new TopK_215();
int res= a.findKthLargest(new int[]{1,3,533,7,8,6,343},2);
System.out.print(res);
}
}
时间复杂度为O(n)证明:https://blog.csdn.net/gaoxueyi551/article/details/89354354
方法二:堆排序
import java.util.PriorityQueue;
public class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
// 使用一个含有 len 个元素的最小堆,默认是最小堆,可以不写 lambda 表达式:(a, b) -> a - b
PriorityQueue<Integer> minHeap = new PriorityQueue<>(len, (a, b) -> a - b);
for (int i = 0; i < len; i++) {
minHeap.add(nums[i]);
}
for (int i = 0; i < len - k; i++) {
minHeap.poll();
}
return minHeap.peek();
}
}
import java.util.Random;
// 手写小根堆
class Solution {
public int findKthLargest(int[] nums, int k) {
int[] ans=new int[k];
for (int i = 0; i <k ; i++) {
ans[i] = nums[i];
}
buildHeap(ans);
// 每次和堆顶进行比较,如果比堆顶还大,就和堆顶交换并重新调整堆
for (int i = k; i <nums.length ; i++) {
if (nums[i] > ans[0]){
ans[0] = nums[i];
adjustHeap(ans,0,ans.length); //buildHeap(ans)
}
}
return ans[0];
}
public static void buildHeap(int[] nums){
for(int i=(nums.length)/2-1;i>=0;i--){
adjustHeap(nums,i,nums.length);
}
}
public static void adjustHeap(int[] a,int parent,int length){
int tmp = a[parent];
int child= parent*2 +1;
while (child < length){
if(child+1 <length &&a[child] > a[child+1]){
child++;
}
if (a[child] < tmp){
a[parent] =a[child];
parent = child;
child = 2*parent+1;
}else{
break;
}
}
a[parent] = tmp;
}
}
参考:
https://zhuanlan.zhihu.com/p/114699207?utm_source=qq