首页 > 其他分享 >LeetCode刷题 -- 分治快排

LeetCode刷题 -- 分治快排

时间:2024-12-03 22:32:26浏览次数:7  
标签:right nums -- ++ 快排 int key LeetCode left

目录

颜色分类

题目链接

题目解析

数组分为三块

在这里插入图片描述

算法原理

1.如果nums[i] == 0,++left, i++下标对应元素交换,先++left后元素对应是1,和0元素交换,再i++

2.如果nums[i] == 2,- -right,i下标对应元素交换,先- -right,对应元素是未知的未扫描的,和2交换,i下标对应元素是未知的,不能++还要进行下一次的判断

3.如果nums[i] == 1,直接++i,因为i下标的左边都是1,++后左边还都是1

在这里插入图片描述

代码

class Solution 
{
public:
    void sortColors(vector<int>& nums) 
    {
        // 三指针,数组分成三块
        int left = -1,i = 0,right = nums.size();
        // i == right结束循环
        // 0 1 2 left边缘到右边 right边缘到左边
        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.三路划分:选出==key,<key,>key的,按照颜色分类那题一样的做法
2.随机选数:选数的范围是在[left,right]中的一个随机值,每一次排序选一个随机数
r = rand() nums[r % (right - left + 1) + left]
再加一个left是因为偏移量,让它能够在[left,right]区间中
[0,n-1-left] -> [left,n-1 ]-> [left,right]

在这里插入图片描述

代码

class Solution 
{
public:
    int func(vector<int>& nums,int l,int r)
    {
        int k = rand();
        // 保证选数在[l,r]之间 
        return nums[k % (r - l + 1) + l];
    }
    void qsort(vector<int>& nums,int l,int r)
    {
        // 有空数组和1个数的数组的情况
        if(l >= r)
        return;
        
        // 选数
        int key = func(nums,l,r);
        int i = l,left = l-1,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]);
        }

        // 递归
        // [l,left] [left + 1,right - 1] [right,r]
        qsort(nums,l,left);
        qsort(nums,right,r);
    }

    vector<int> sortArray(vector<int>& nums) 
    {
        srand(time(NULL));// 设置随机数的种子
        // 数组分成三份  优化随机选数
        qsort(nums,0,nums.size()-1);
        return nums;
    }
};

数组中第K个最大元素

题目解析

在这里插入图片描述

算法原理

1.可以用堆排序找第K大的元素
2.还可以用快排的选择
快排的选择跟上一题的逻辑很像

第K大的元素一定落在第一次数组分成三份的某一个区间内,所以只要去其中一个区间用快排可以解决,要注意的是第三种情况,传k时要传k-b-c,a,b,c都表示区间中元素的个数,k-b-c表示在第一个区间内找第K大的

第一种情况在c中找第K大的
第二种第K大的落在里面就是key了

在这里插入图片描述

代码

class Solution 
{
public:
    // 把数组分成三份
    int Selectnums(vector<int>& nums,int left,int right)
    {
        // 随机选数
        int r = rand();
        return nums[r % (right - left + 1) + left];
    }
    int qsort(vector<int>& nums,int left,int right,int k)
    {
        //返回条件
        // 只有一个元素
        // 没有空数组的情况因为要找第K大的数,至少要有一个数,有一个数的数组
        if(left == right)
        return nums[left];

        int key = Selectnums(nums,left,right);
        int i = left,l = left - 1,r = right + 1;
        while(i < r)
        {
            if(key == nums[i]) i++;
            else if(key > nums[i]) swap(nums[++l],nums[i++]);
            else swap(nums[--r],nums[i]);
        }

        // 递归
        // [left,l] [l+1,r-1] [r,right]
        // [0,l++]            [r--,n-1]
        int a = l - left + 1;
        int b = r - l - 1;
        int c = right - r + 1;
        if(c >= k)
        return qsort(nums,r,right,k);
        else if((b+c) >= k)
        return key;
        else
        return qsort(nums,left,l,k - b - c);
    }
    int findKthLargest(vector<int>& nums, int k) 
    {
       // 随机选数
       srand(time(NULL));
       int n = nums.size();
       
       return qsort(nums,0,n-1,k);
    }
};

LCR 159. 库存管理 III

题目链接

题目解析

以任意顺序返回题目中的K个最小元素

在这里插入图片描述

算法原理

快速选择算法和上一题类似

  1. a个 > k个,在[l,left]区域排序最小的k个元素
  2. a + b个 >= k个,在[l,right]区域中,直接返回key,因为key左边(包括key)一定是排好大小的,所以返回
  3. 前二种情况都不满足,在[right,r]区域中找k-a-b个最小的元素
  4. a == k的情况,肯定排好了,直接返回,因为<=key这变都是有序的
  5. [2,5,7,4] -> 2作为key [2,4,5,7]是排好后的
    [2,4,5,7]这种a > k还要排序,k在key的后面
    [2,5,7,4] -> 5作为key [2,4,5,7]是排好后的
    key 左边都是有序的

在这里插入图片描述

代码

class Solution 
{
public:
    // 随机选数
    int GetRound(vector<int>& nums,int left,int right,int k)
    {
        int r = rand();
        return nums[r % (right - left + 1) + left];
    }
    vector<int> inventoryManagement(vector<int>& stock, int cnt) 
    {
        srand(time(NULL));
        qsort(stock,0,stock.size()-1,cnt);
        return {stock.begin(),stock.begin()+cnt};
        // int n = stock.size();
        // sort(stock.begin(),stock.end());
        // vector<int> ret;
        // int i = 0;
        // while(cnt--)
        // {
        //     ret.push_back(stock[i++]);
        // }
        // return ret;
    }
    void qsort(vector<int>& nums,int l,int r,int k)
    {
        if(l >= r) return;

        int key = GetRound(nums,l,r,k);
        int i = l,left = l - 1,right = r + 1;
        while(i < right)
        {
            if(key > nums[i]) swap(nums[++left],nums[i++]);
            else if(key == nums[i]) i++;
            else swap(nums[--right],nums[i]);
        }

        // [l,left] [left + 1,right - 1] [right,r]
        int a = left - l + 1,b = right - left - 1,c = r - right + 1;
        if(a > k) qsort(nums,l,left,k);
        else if(a + b >= k) return;
        else qsort(nums,right,r,k - a - b);
    }
};

标签:right,nums,--,++,快排,int,key,LeetCode,left
From: https://blog.csdn.net/2301_79722622/article/details/144155672

相关文章

  • Pwn-栈溢出
    原理基本的栈帧结构(以x64的栈为例)(图片摘自Hello-CTF)RBP为栈底寄存器,RSP为栈顶寄存器,分别记录了栈帧中记录数据部分的起始和终止地址。函数的临时变量的在内存中的位置都是通过这两个寄存器加减偏移确定的。栈底分别还记录了上一个栈帧的RBP的值,以及函数的返回地址。......
  • [免费]基于Python的Django在线(生鲜)商城(电子商城)管理系统【论文+源码+SQL脚本】
    大家好,我是java1234_小锋老师,看到一个不错的基于Python的Django在线(生鲜)商城(电子商城)管理系统,分享下哈。项目视频演示【免费】基于Python的Django在线(生鲜)商城(电子商城)管理系统Python毕业设计_哔哩哔哩_bilibili项目介绍随着电子商务的迅速发展,在线商城作为现代......
  • 1.1 Beginner Level学习之“了解 ROS 服务和参数”(第七节)
    学习大纲:1.ROS服务ROS服务是一种节点之间的通信方式,允许一个节点发送请求并接收响应。它采用的是同步机制,即一个节点会发送请求,等待另一个节点处理并返回结果。这个机制适合需要及时反馈的情况。rosservice是ROS提供的一个工具,专门用来与服务进行交互。它可以列出、查......
  • 《code》 14th “反馈与触发器”
    文章目录1.振荡器2.触发器3.D型锁存器(电平触发)4.2-1选择器5.带锁存器的加法计算器6.新型加法计算器7.边沿触发的锁存器8.分频器和行波计数器9.计算振荡器的频率10.带预置和清零的边沿型D触发器1.振荡器电路的输出,要么提供电压,要么不提供电压。或者可......
  • 《Python基础》之Pandas库
    目录一、简介二、Pandas的核心数据结构1、Series2、DataFrame三、数据读取与写入1、数据读取 2、数据写入四、数据清洗与处理1、处理缺失值2、处理重复值3、数据转换五、数据分析与可视化1、统计描述2、分组聚合3、数据可视化六、高级技巧1、时间序列分析2......
  • mybatis集成篇(二)--Springboot集成mybatis
    前言随着Spring框架越来越成熟,推出的Springboot使用也越来越广,Mybatis随其自然地适配Springboot。Springboot集成Mybatis使用application.yml配置mybatis:mapper-locations:classpath:./mapper/*Mapper.xmlconfiguration:map-underscore-to-camel-case:tru......
  • 奇酷星球 1.1.2 | 免费听歌神器,三条音源,可下载
    奇酷星球(DX云音乐)是一款优质的音乐播放器,拥有强大的音乐库,涵盖了各种风格和国家的音乐作品。无论你喜欢流行曲、古典乐、摇滚还是电子音乐,都能在这里找到满足自己音乐口味的作品。大小:35M下载地址:百度网盘:https://pan.baidu.com/s/10UjSltMTA-skHb7CUrDOEw提取码:cizu......
  • Bandizip 6.29|最好用的解压缩软件,最后的免费版
    Bandizip曾是一款备受推崇的桌面解压缩软件。尽管自从推出会员版本后讨论度有所下降,但其强大的功能依然受到用户的喜爱,包括极致的解压缩速度和多种自定义压缩选项。最后一个免费版本提供了简洁美观的界面,并且完全无广告。去升级提示的方法是删除安装目录下的update升级程序......
  • 鲁大师 6.1024 | 某大佬的最终绿化版,去除无用功能和广告
    鲁大师是一款知名的硬件检测软件,许多用户喜欢使用它来测试电脑性能。然而,原版软件中包含大量广告和不必要的功能。某大佬对鲁大师进行了绿化处理,精简了许多无用的功能,去除了广告,并确保退出后没有后台残留进程。该版本是大佬的最终完结版,具有以下特点:1.完整精简了功能区中......
  • HookVip4.0.3 | 可解锁各大应用会员
    HookVip是一款可以解锁会员的模块工具,需要搭配相应框架结合使用。这款插件工具支持多种框架如LSPosed、LSPatch、太极、应用转生等,并且完全免费,占用内存小。支持的软件包括now要想、神奇脑波、塔罗牌占卜、爱剪辑、人人视频、咪萌桌面宠物、音频裁剪大师、飒漫画、ES文件浏......