• 求第k小的数


    题目链接:第k个数

    题意:求n个数中第k小的数

    题解:

    //由快速排序算法演变而来的快速选择算法
    #include<iostream>
    using namespace std;
    const int N=1e5+10;
    
    int a[N];
    //k是整个区间中的第k小的数。
    void quick(int l,int r,int k)
    {//快速选择算法保证每次递归时都递归到答案所在的区间.
        int i=l-1,j=r+1,x=a[l+r>>1];
        if(l>=r)return a[r];
        while(i<j)
        {
            while(a[++i]<x);
            while(a[--j]>x);
            if(i<j)swap(a[i],a[j]);
        }
        
        cout<<"i:   "<<i<<"j:   "<<j<<"x:   "<<x<<endl;
        quick(l,j);
        quick(j+1,r);
    }
    /*
    5
    2 3 4 5 1
    i:   3j:   2x:   4
    i:   2j:   1x:   3
    i:   1j:   0x:   2
    i:   4j:   3x:   5
    1 2 3 4 5
    通过一组测试数据发现i+1==x,i-1=j; j是x在数组中的下标
    得到数组中比<=x的数有j+1个
    扩展问题:求第k大的数
    
    基础问题:求第k小的数
    每次统计<=x的数的个数及j+1,如果j+1<=cnt左边去递归
    否则右边去递归
    */
    int main()
    {
        int n,k;cin>>n>>k;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        quick(0,n-1,k);
        for(int i=0;i<n;i++)
            printf("%d ",a[i]);
        return 0;
    }
    
    

    代码:

    #include<iostream>
    using namespace std;
    
    const int N=1e6+10;
    
    int a[N];
    
    int quick(int l,int r,int k)
    {
        int i=l-1,j=r+1,x=a[l+r>>1];
        if(l>=r)return a[l];
        while(i<j)
        {
            while(a[++i]<x);
            while(a[--j]>x);
            if(i<j)swap(a[i],a[j]);
        }
        int sl=j-l+1;
        if(sl>=k)
        quick(l,j,k);
        else
        quick(j+1,r,k-sl);
    }
    
    int main()
    {
        int n,k;cin>>n>>k;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        cout<<quick(0,n-1,k);
        
    }
    
  • 相关阅读:
    适配器模式
    第五章项目:QuickHit
    试题分析(第二套)
    试题分析(第一套)
    新闻发布系统(分页显示)
    jsp九大内置对象
    文件上传
    jsp统测
    新闻发布系统(首页)
    URL和URI的区别
  • 原文地址:https://www.cnblogs.com/forward-985/p/13352968.html
Copyright © 2020-2023  润新知