题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例1
输入
[1,3,5,2,2],5,3
返回值
2
代码如下:
import java.util.*;
//有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
//给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
/**
* findKth:快排思路找第k大的数 (这里的partion改变了快排的,大数在前面,小数在后面)
* findKth1:优先级队列找第k大的数
* findkth2:快排找第k小的数 (这里的partion还是快排的,没有变,小数在前面,大数在后面)
*/
public class test {
public static void main(String[] args) {
int[] array = {1,2,3,4,646,6,7};
System.out.println(findKth(array, 7, 3));//第k大的快排解法
System.out.println(findKth2(array, 7, 3));//第k小的快排解法
System.out.println(findKth1(array, 7, 3));//第k大的队列解法
}
//快排方法
//找第K小的数
public static int findKth2(int[] a, int n, int K) {
// write code here
int low = 0;
int high = n-1;
return quick2(a,low,high,K);
}
public static int quick2(int[] ar, int low, int high, int k) {
int par = partion2 (ar, low, high,k);
if(k == par + 1) {
return ar[par];
} else if (k > par + 1){
return quick2( ar, par+1,high,k);
} else {
return quick2(ar,low,par -1,k);
}
}
public static int partion2(int[] a, int start , int end,int k) {
int tmp = a[start];
while(start < end) {
while(start < end && a[end] >= tmp) {
end--;
}
if(start >= end) {
break;
}else{
a[start] = a[end];
}
while(start < end && a[start] <= tmp) {
start++;
}
if(start >= end) {
break;
}else{
a[end] = a[start];
}
}
a[start] = tmp;
return start;
}
//快排方法
//找第K大的数
public static int findKth(int[] a, int n, int K) {
// write code here
int low = 0;
int high = n-1;
return quick(a,low,high,K);
}
public static int quick(int[] ar, int low, int high, int k) {
int par = partion (ar, low, high,k);
if(k == par + 1) {
return ar[par];
} else if (k > par + 1){
return quick( ar, par+1,high,k);
} else {
return quick(ar,low,par -1,k);
}
}
public static int partion(int[] a, int start , int end,int k) {
int tmp = a[start];
//这里是把大的元素往前面放了
while(start < end) {
while(start < end && a[end] <= tmp) {//注意这里
end--;
}
if(start >= end) {
break;
}else{
a[start] = a[end];
}
while(start < end && a[start] >= tmp) {//注意这里
start++;
}
if(start >= end) {
break;
}else{
a[end] = a[start];
}
}
a[start] = tmp;
return start;
}
//队列方法
public static int findKth1(int[] a, int n, int K) {//已经通过
// write code here
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (int i = 0; i < n; i++) {
queue.offer(a[i]);
if (queue.size() > K) {
queue.poll();
}
}
return queue.peek();
}
}
解题思路:
题目要求用快排的思想来解题,首先topk的问题用优先级队列来解决是非常快的,还有就是直接暴力Arrays.sort()然后取下标,(不可取哦),按照题目意思既然可以找第k大的,那么稍微改一下就可以找第k小的了,一切尽在代码里面。你懂的!!!!!