快排思想 求第(前)k大数

#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5+10;
int vis[MAX_N];
int ans;
int solve(int l,int r)
{
    int p = vis[l];
    while(l<r)
    {
        while(l<r && vis[r]>=p)
            r--;
        swap(vis[r],vis[l]);
        while(l<r && vis[l]<=p)
            l++;
        swap(vis[r],vis[l]);
    }
    vis[l] = p;
    return l;
}
int qsort_k(int l,int r,int k)
{
    if(l<r)
    {
        int t=solve(l,r);
        if(t < k)
            qsort_k(t+1,r,k);
        else if(t == k)
            ans = vis[k];
        else
            qsort_k(l,t-1,k);
    }
    //由于这里只进行了一次递归,在理想情况下时间复杂度T(n)=T(n/2)+n,T(1)=1;O(n)的时间复杂度
}
int main()
{
    //快排思想求第k大的数
    int n;//输入n个数
    int k;
    while(cin>>n>>k)
    {
        for(int i=0; i<n; i++)
            cin>>vis[i];
        qsort_k(0,n-1,k-1);
        cout<<ans<<endl;
    }
    return 0;
}
基本思想:
由于快排的partition函数返回的枢轴位置刚好是左边都比他小,右边都比他大,那我们可以利用这一特点,将其与K比较,可以减少一次递归;假如返回的枢轴位置t比k大,那么
t到n的部分不必再关心,反之,0到t部分不必再关心
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值