问题描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
输入描述:
输入一个数组、数组长度、k大
输出描述:
输出k大坐标
示例
示例1
输入
[1,3,5,2,2],5,3
输出
2
解决思路
分析
本题与之前的最小的K个数思路相类似,有兴趣的小伙伴可以看看之前的文章,这里只通过变形的快速排序实现。
方法
- 通过快速排序的思路实现,当快速排序后的基准值与K相等时,则找到了第K大值(快速排序此处用的降序排序)。
代码实现
public class Solution {
public int findKth(int[] a, int n, int K) {
// write code here
return find(a, 0, n - 1, K);
}
public int find(int[] a, int start, int end, int K) {
// 找基准
int povitIndex = partition(a, start, end);
// 判断基准跟k的关系
if (povitIndex + 1 < K) {
return find(a, povitIndex + 1, end, K);
}
if (povitIndex + 1 > K) {
return find(a, start, povitIndex - 1, K);
}
// 当基准等于K时,返回
return a[povitIndex];
}
// 降序排列
private int partition(int[] a, int start, int end) {
int i = start;
int j = end + 1;
int povit = a[start];
while (true) {
// 从左往右找第一个小于基准值的
while (a[++i] > povit) {
// 如果i超过end范围,跳出,说明没有大于基准值的
if (i >= end) break;
}
// 从右向左找第一个大于基准值的
while (a[--j] < povit) {
// 如果j超过start,跳出,说明没有小于基准值的
if (j <= start) break;
}
// 如果i大于j,跳出,不需要交换
if (i >= j) break;
// 小于基准值的元素和大于基准值的元素交换,大于基准值的元素往后,小于基准值的元素往前
exchange(a, i, j);
}
// 交换0和大于基准值的元素,因为是降序排列
exchange(a, start, j);
return j;
}
// 交换值
private void exchange(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
小伙伴如果想测试的话,可以直接到牛客网这个链接做测试