随机快排和习题

随机快排

不稳定:当选择的x越靠经两侧,时间复杂度为O(n^2),空间复杂度O(n)

当选择的x越靠近中间,时间复杂度为O(n*log n),空间复杂度为O(logn)

912. 排序数组 - 力扣(LeetCode)

int static small;//设置全局区的静态变量,来定义排序x的位置后,在快排时的左右边界。
int static big;
class Solution {
public:
    void partition(vector<int>& nums,int left,int right,int x)
    {
         small = left;//小于x的分界处
         big = right;//大于x的分界处
         int i = left;
         while(big>=i)
         {
             if (nums[i] < x)
             {
                 swap(nums[i++], nums[small++]);
             }
             else if (nums[i] > x)
             {
                 swap(nums[i], nums[big--]);
             }
             else
             {
                 i++;
             }
         }
    }
    void quickSort(vector<int>& nums,int left,int right)
    {
        if (left>=right)
        {
            return;
        }
        std::random_device rd; // 获取随机种子
        std::mt19937 gen(rd()); // 使用mt19937引擎
        std::uniform_int_distribution<int> distribution(left,right); // 生成[min, max]范围内的随机整数
        int randomNumber = distribution(gen);
        int x = nums[randomNumber];
        partition(nums, left, right, x);//给x对应的值进行排序
        int a = small;//这里保存了samll和big的值,是因为quickSort函数执行后,small和big的值会改变。
        int b = big;
        quickSort(nums,left,a-1);
        quickSort(nums,b+1,right);
​
​
    }
​
};
​
​

2.给定一个无需数组,求第k大的数,并且返回k的值

思路:使用按照随机快排的方式,先随机一个数组的下标x,对其进行排序,再根据small-1和big+1的位置,查找是否x已经在范围内,如果不在就在对应一侧进行相同操作即可。

时间复杂度O(N) 空间复杂度O(1)

int static small;
int static big;
class Solution {
public:
    void partition(vector<int>& nums,int left,int right,int x)
    {
         small = left;//小于x的分界处
         big = right;//大于x的分界处
         int i = left;
         while(big>=i)
         {
             if (nums[i]<x)
             {
                 swap(nums[small++],nums[i++]);
             }
             else if(nums[i]>x)
             {
                 swap(nums[big--],nums[i]);
             }
             else
             {
                 i++;
             }
         }
    }
​
    int quickSort(vector<int>&nums,int key)
    {
        int left = 0;
        int right = nums.size() - 1;
        for (int i=0;i<nums.size();i++)
        {
            std::random_device rd; // 获取随机种子
            std::mt19937 gen(rd()); // 使用mt19937引擎
            std::uniform_int_distribution<int> distribution(left, right); // 生成[min, max]范围内的随机整数
            int randomNumber = distribution(gen);
            int x = nums[randomNumber];
            
            partition(nums,left,right,x);
            if (small-1>key)
            {
                right = small - 1;
            }
            else if (big+1<key)
            {
                left = big + 1;
            }
            else
            {
                return nums[small];
            }
        }
    }
    //给定无序数组,找到第k大的数并且返回
    int randomselect(vector<int>& nums,int k)
    {
        //找第k大的数,其实就是第n-k个。
        return quickSort(nums,nums.size()-k);
    }
​
};

​​​​​​​

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值