• 从一个无序数组中求出第K大/小的数


    这个题目可以作为练习写大/小根堆的实现,不过貌似时间复杂度还是蛮高的。在洛谷上面一道模板题上面好像就超时了几个点,不知道是不是我实现的问题。那么除此之外,最容易想到的方法是先对该数组进行排序,然后取出第K或MAX-K数来。当选择使用快排的时候,时间复杂度是$O(nlogn)$。但还有一种更优的方法是利用快排划分出来的主元位置再递归寻找,这种方法叫作随机选择算法。它对任何输入都可以达到$O(n)$的期望时间复杂度。

     

    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    
    //随机选择主元 其实也是快排的一种写法 
    int randPartition(int A[],int left,int right)
    {
        // rand()/RAND_MAX得到一个0~1的小数再乘以相差值right-left最后加到left四舍五入得到随机值 
        int p = round(1.0*rand()/RAND_MAX*(right-left)+ left);
        swap(A[p],A[left]);
        int temp = A[left];
        while(left<right)   // 跳出循环时left==right 
        {
            while(left < right && A[right]>temp)
                right--;
            A[left] = A[right];
            while(left < right && A[left]<=temp)
                left++;
            A[right] = A[left];
        } 
        A[left] = temp;
        return left;
    } 
    
    //递归实现查询K值 
    int randSelect(int A[],int left,int right,int k)
    {
        if(left == right)
            return A[left];
        int index = randPartition(A,left,right);
        int M = index-left+1; // 表示从左到右第M个数 
        if(M==k)
            return A[index];
        if(M<k) 
                    randSelect(A,index+1,right,k-M); //注意 k-M 
            else if(M>k)
            randSelect(A,left,index-1,k);
    }
  • 相关阅读:
    2019-11-4:渗透测试,bypass学习,笔记
    2019-11-3:渗透测试,基础学习,bypass类型笔记
    Linux常用命令集合
    HBase(0.96以上版本)过滤器Filter详解及实例代码
    Hadoop安全模式
    Linux学习笔记--一些错误的记录
    GUG记录
    为什么 1000 == 1000会返回false,100 == 100会返回true
    关于解决mysql数据库乱码的问题
    《MVC实现用户权限》
  • 原文地址:https://www.cnblogs.com/kachunyippp/p/10256659.html
Copyright © 2020-2023  润新知