寻找第k大
思路:快排+二分
1.对于快排,先设置第一个数为基准数
2.设置一个指针i指向区间的左端点,设置一个指针j指向区间的右端点
3.只要两个指针没有相遇,即i<j,就继续循环
4.i指针只要还没有与j指针相遇(i<j),如果要进行升序,就让i去找比基准大的数,这样交换后就是大数在后
5.j指针只要还没有与j指针相遇(i<j),如果要进行升序,就让j去找比基准小的数,这样交换后就是小数在前
5.降序操作相反
6.只要两个指针没有相遇,就将两个数交换
7.最后将基准数与指针相遇的位置的值进行交换
8.递归求[l,i-1]区间和[i+1,r]区间进行快排
用二分的思想去找第k大的数,因为已经是有序的,所以可以用二分进行查找
代码:
class Solution {
public:
//快排函数
int quick_sort(vector<int>& a,int l,int r,int k){
//设置一个基准数:一般设置第一个数为基准数
//设置两个指针:左指针指向区间的左端点,右指针指向区间的右端点
int temp=a[l];
int i=l,j=r;
//只要两个指针还没有相遇,就继续循环
while(i<j){
//只要指针没有相遇,且由于要降序,所以j指针是去找比基准数大的,之后交换后就可以使得大的数在前面
while(i<j&&a[j]<=temp){
j--;
}
//只要两个指针还没有相遇,且是降序,所以i指针是去找比基准数小的数,之后交换后就可以使小的数在后面
while(i<j&&a[i]>=temp){
i++;
}
//只要指针没有相遇,就交换两者的值
if(i<j){
swap(a[i],a[j]);
}
}
//最后将基准数与相遇的那个位置的值交换,注意交换的a数组中的元素,所以是a[l]而不是temp
swap(a[i],a[l]);
//如果发现刚好找到第k个数,就返回第k大的数的值
if(i+1==k){
return a[i];
}else if(i+1<k){
//否则就去[i+1,r]的区间继续找
return quick_sort(a,i+1,r,k);
}else {
//否则就去[l,i-1]的区间找第k大的数
return quick_sort(a,l,i-1,k);
}
}
int findKth(vector<int>& a, int n, int K) {
//快排,传入需要排序的序列的区间的左右端点,由于下标从0开始,所有区间的所有端点是0和n-1
return quick_sort(a,0,n-1,K);
}
};