【C++】分治-快速排序算法习题


🎆个人主页:夜晚中的人海

今日语录:你有多自信,世界就有多相信你!你有多坚持,成功就有多眷顾你!

文章目录

⭐一、颜色分类

题目链接:颜色分类

题目内容:

解题思路:

1.使用快排的思想,定义三个指针,分别是left(初始化为-1,用于标记0序列末尾)i(初始化为0,用于扫描整个数组)right(初始化为数组大小n,标记2序列的起始位置)

2.在 i 扫描数组时,我们就将数组分成三块区域:[0,left]区间表示0元素,[left + 1,i - 1]表示1元素,[i,right - 1]表示代排列元素,[right,n]表示2元素

代码实现:

cpp 复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int left = -1,i = 0,right = nums.size();
        while(i < right)
        {
            if(nums[i] == 0)
            {
                swap(nums[++left],nums[i++]);
            }
            else if(nums[i] == 1)
                i++;
            else
            {
                swap(nums[--right],nums[i]);
            }
        }
    }
};

🏠二、排序数组

题目链接:排序数组

题目内容:

解题思路:

1.使用数组分三块区域以及随机选择基准值的快速排序方法

2.将产生的随机数转化为随机下标,按照划分区域规则,将数组划分成:[l,left],[left + 1,right - 1],[right,r]

3.然后递归处理左区域和右区域,最终得到结果

代码实现:

cpp 复制代码
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) 
    {
        srand(time(NULL));
        qsort(nums,0,nums.size() - 1);
        return nums;
    }

    void qsort(vector<int>& num,int l,int r)
    {
        if(l >= r)
            return;
        int key = getrandom(num,l,r);
        //将数组划分成三块区域
        //[l,left][left + 1,right - 1][right,r]
        int i = l,left = l - 1,right = r + 1;
        while(i < right)
        {
            if(num[i] < key)
            {
                swap(num[++left],num[i++]);
            }
            else if(num[i] == key)
                i++;
            else
            {
                swap(num[--right],num[i]);
            }
        }
        //递归排序左右区间
        qsort(num,l,left);
        qsort(num,right,r);
    }
		//获取随机值
    int getrandom(vector<int>& num,int left,int right)
    {
        int r = rand() % (right - left + 1) + left;
        return num[r];
    }
};

🚀三、数组中的第K个最大元素

题目链接:数组中的第K个最大元素

题目内容:

解题思路:

1.根据快排的思想,定义三个指针,将数组分成三块

2.然后通过计算每一块区域内元素的个数,从而推断出我们要找的第k大元素在哪一块区域,然后到相应的区域去寻找结果

代码实现:

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        srand(time(NULL));
        return qsort(nums,0,nums.size() - 1,k);
    }

    int qsort(vector<int>& nums,int l,int r,int k)
    {
        if(l == r)
            return nums[l];
        //获取随机基准值
        int key = getrandom(nums,l,r);
        int left = l - 1,i = l,right = r + 1;
        //将数组分成三块区域
        //[l,left][left + 1,right - 1][right,r]
        while(i < right)
        {
            if(nums[i] < key)
            {
                swap(nums[++left],nums[i++]);
            }
            else if(nums[i] == key)
            {
                i++;
            }
            else
            {
                swap(nums[--right],nums[i]);
            }
        }
        //分情况讨论
        int c = r - right + 1,b = right - left - 1;
        if(c >= k)
            return qsort(nums,right,r,k);
        else if(b + c >= k)
            return key;
        else
            return qsort(nums,l,left,k - b - c);
    }
		//获取随机值
    int getrandom(vector<int>& nums,int left,int right)
    {
        return nums[rand() % (right - left + 1) + left];
    }
};

🏖️四、最小的K个数

题目链接:最小的K个数

题目内容:

解题思路:

1.运用快排的思想,跟上一个题目的解法类似,也是定义三个指针

2.将数组划分三块区域 ,然后通过计算每一块区域中元素的个数确定我们最小的第k个数在第几块区域,然后在这块区域找到结果并返回

代码实现:

cpp 复制代码
class Solution {
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) {
        srand(time(NULL));
        qsort(stock,0,stock.size() - 1,cnt);
        return {stock.begin(),stock.begin() + cnt};
    }

    void qsort(vector<int>& nums,int l,int r,int k)
    {
        if(l >= r)
            return;
        //随机获取基准值
        int key = getrandom(nums,l,r);
        //将数组划分三块区域
        int left = l - 1,i = l,right = r + 1;    
        while(i < right)
        {
            if(nums[i] < key)
            {
                swap(nums[++left],nums[i++]);
            }
            else if(nums[i] == key)
            {
                i++;
            }
            else
            {
                swap(nums[--right],nums[i]);
            }
        }
        //分类讨论
        int a = left - l + 1,b = right - left - 1;
        if(a >= k)
            qsort(nums,l,left,k);
        else if(a + b >= k)
            return;
        else
            qsort(nums,right,r,k - a - b);
    }
	//获取随机值
    int getrandom(vector<int>& nums,int left,int right)
    {
        return nums[rand() % (right - left + 1) + left];
    }
};

今天的分享就到这里啦,希望可以帮到您,感谢您的阅读,我们下期再见!

相关推荐
星轨初途3 分钟前
数据结构排序算法详解(2)——选择排序(附动图)
c语言·数据结构·经验分享·笔记·b树·算法·排序算法
共享家95274 分钟前
QT-界面优化(下)
开发语言·数据库·qt
合作小小程序员小小店6 分钟前
游戏开发,桌面%小游戏,俄罗斯方块%demo,基于vs2022,c语言,背景音乐,easyX,无数据库,
c语言·开发语言
27399202928 分钟前
生成二维码 QRCode (QT)
开发语言·qt
火山灿火山38 分钟前
初识Qt(使用不同中方式创建helloworld)
开发语言·qt
phdsky44 分钟前
【设计模式】抽象工厂模式
c++·设计模式·抽象工厂模式
BD_Marathon1 小时前
sbt 编译打包 scala
开发语言·后端·scala
雾岛听蓝1 小时前
C++ 入门核心知识点(从 C 过渡到 C++ 基础)
开发语言·c++·经验分享·visual studio
7***37452 小时前
Java设计模式之工厂
java·开发语言·设计模式
上不如老下不如小2 小时前
2025年第七届全国高校计算机能力挑战赛初赛 Python组 编程题汇总
开发语言·python·算法