题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
测试样例
[1,3,5,2,2],5,3
返回:2
牛客链接:
https://www.nowcoder.com/practice/e016ad9b7f0b45048c58a9f27ba618bf?tpId=188&&tqId=35311&rp=1&ru=/ta/job-code-high-week&qru=/ta/job-code-high-week/question-ranking
解题思路
首先根据快排思想进行数组排序,但不必进行全部的排序,找到位置位于第n-K上的数字即可,即当获取的下标等于n-K时,就不必再进行后面的快排运算
class Finder {
public:
int findKth(vector<int> a, int n, int K) {
quickSort(a, n, K, 0, n-1);
return a[n-K];
}
void quickSort(vector<int> &a, int n, int K,int begin, int end) {
if (begin == end) {
return ;
}
int low = begin;
int high = end;
int flag = a[begin];
while (low < high) {
//从右向左扫描,找到后面比flag小的数
while (low < high && a[high] >= flag) {
high--;
}
//将将右子数组中不合格的元素放到左边不合格元素的位置(原元素已经移走)
if (low < high) {
a[low] = a[high];
}
//从左向右扫描,找到前面比flag大的数
while (low < high && a[low] <= flag) {
low++;
}
//将左子数组中不合格的元素放到左边不合格元素的位置(原元素已经移走)
if (low < high) {
a[high] = a[low];
}
}
// 将基准元素放到中间位置
a[low] = flag;
//如果右侧数字个数比K多,则在右侧找第K大的数
if (low < n-K) {
quickSort(a, n, K, low+1, end);
}
//如果右侧数字个数不够K个,则从左侧找第k大的数
else if (low > n-K) {
quickSort(a, n, K, begin, low-1);
}
else if (low == n-K) {
return ;
}
}
};
注意:
快速排序中前后位置元素的移动,和快排中循环条件的设置