题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例
输入:
[1,3,5,2,2],5,3
输出:
2
思路1:
首先想到的就是对数组先进行排序,然后输出倒数第K的数字的下标=数组的长度-k;
所以问题就直接分解成为了如何对数组进行排序的问题,第一种就是直接利用java官方的API,Arrays.sort(array);进行排序,虽然这样得出来的答案是正确的,但是题目要求的是使用快排的思路。
public static int findKth(int[] a, int n, int K) {
if(K>n)
return 0;
Arrays.sort(a);
return a[n-K];
}
思路2:
使用快排的思路对数组元素进行排序:
快排的思路主要分为三部分:
(1)找基准值;
(2)partition部分(Hoare法,挖坑法,前后遍历法)
(3)对左右两个子区间分别进行排序;
//交换两个数字
public static void swap(int[] array,int index1,int index2){
int tmp=array[index1];
array[index1]=array[index2];
array[index2]=tmp;
}
//partition部分
public static int partition(int[] array,int lowIndex,int highIndex){
int leftIndex=lowIndex;
int rightIndex=highIndex;
//作为基准值的是最左边的一个数
int key=array[lowIndex];
while(leftIndex<rightIndex){
while(leftIndex<rightIndex&&array[rightIndex]>=key){
rightIndex--;
}
while(leftIndex<rightIndex&&array[leftIndex]<=key){
leftIndex++;
}
//否则就进行交换
swap(array,leftIndex,rightIndex);
}
swap(array,lowIndex,leftIndex);
return leftIndex;
}
//快排具体实现部分
public static void quickSortInternal(int[] array,int lowIndex,int rightIndex){
int size=rightIndex-lowIndex+1;
if(size<=1){
return ;
}
//对左右两个区间分别进行排序
int keyIndex=partition(array,lowIndex,rightIndex);
quickSortInternal(array,lowIndex,keyIndex-1);
quickSortInternal(array,keyIndex+1,rightIndex);
}
public static void quickSort(int[] array){
quickSortInternal(array,0,array.length-1);
}
public static int findKth2(int[] a, int n, int K) {
//利用快排先进行数组元素的排序
quickSort(a);
return a[n-K];
}