leetcodeT912-快排优化-三路划分

简介: leetcodeT912-快排优化-三路划分

1.前言

因为快排的名声太大

并且快排在某些场景下比较慢,所以leetcode"修理"了一下快排

特意设计了一些专门针对快排的测试用例

所以用快排过不了这一题

2.为什么需要三路划分的优化?

我们遇到了第一个为难快排的测试用例全是重复值2

我们发现快排在遇到全是重复值的数据时,

这里以左右指针法为例

每次右指针从右向左找小时都要跑到左指针位置处

然后进行交换,递归

每次都只能把那个重复数据2放到当前递归区间的起始位置,就像是冒泡排序一样每次只能冒一个数到对应位置,但是冒泡排序好歹还能有一个优化(没有发生数据交换时即为有序,排序结束),可是这时快排连优化都没有

退化到了O(n^2)的时间复杂度

3.三路划分的思想及举例画图

这是整个过程,大家也可以自己对照三种情况画一下

一趟三路划分

前:

后:

我们发现:

一趟三路划分后整个数组被分为三个部分:

假设区间左端点:begin,右端点:end

[begin,l-1]:这一段上区间的值小于key

[l,r] :这一段上区间的值等于key

[r+1,end]:这一段上区间的值大于key

等于key的那一段区间不需要递归了,因为它们已经位于它们该在的地方了

接下来只需要递归[begin,l-1],[r+1,end]即可

4.三路划分的代码实现

//三路划分
void QuickSort(int* a, int begin, int end)
{
  if(begin>=end)
    {
        return;
    }
    int keyIndex=GetMidIndex(a,begin,end);
    Swap(&a[begin],&a[keyIndex]);
    int key=a[begin];
    int left=begin,right=end,cur=begin+1;
    while(cur<=right)
    {
        if(a[cur]<key)
        {
            Swap(&a[cur],&a[left]);
            cur++;
            left++;
        }
        else if(a[cur]==key)
        {
            cur++;
        }
        else
        {
            Swap(&a[cur],&a[right]);
            right--;
        }
    }
    QuickSort(a,begin,left-1);
    QuickSort(a,right+1,end);
}

所以我们可以发现,三路划分之后,数组中重复越多,我们快排就越快

因为重复值直接就跳过了

对于那个测试用例来说

第一趟排序之后left还是等于begin,right还是等于end

所以再往下递归就会触发begin>=end这个条件,就会直接返回

所以达到了O(n)的时间复杂度

所以对于这个测试用例来说已经比较快了

5.三数取中修改

但是:

尽管我们通过了所有的测试用例,但是因为耗时太长leetcode直接针对快排

那么怎么办,怎么过呢?

我们去掉三数取中优化,看一下是哪个测试用例对我们的针对

这里我们打印了一下数组开头,中间,结尾的那三个数

这个题目最大值是50000,

这个测试用例最大值是上万,而我们三数取中取出来的是7500,相对来说偏小了

所以我们要对三数取中的mid搞一个随机数

只需要在三数取中的代码中给mid一个随机值即可

这里设置随机数种子,避免出现rand函数产生的重复值不变的情况

尽管我们过是过了,但是Leetcode这一题的测试用例太针对快排了

所以快排被欺负的很惨

以上就是leetcodeT912针对快排的三路划分优化的讲解,希望能对大家有所帮助!

相关文章
|
关系型数据库
NR PDCCH (三)DCI传输过程
PDCCH 承载的data就是DCI,在PDCCH 盲检时需要用正确的RNTI进行解扰和CRC校验,才能确认DCI是不是发送给UE的,为什么是这样的decode 流程?这主要DCI的调制过程有关系,下面来具体看。
|
Oracle Java Unix
Java/JDK下载、安装与环境变量配置超详细教程(2022更新)保姆级,秒会
Java/JDK下载、安装与环境配置超详细教程(2022更新)保姆级,小白秒会[学习必备,建议收藏]。包含JDK8、JDK11、JDK17、JDK19等,本文将从JDK的下载与安装讲起,在从配置到第一个HelloWrold实践结束。在观看本文前我们需要知道JDK是什么,有什么作用?JDK是Java的开发工具包,包括JVM虚拟机,核心类库,开发工具。
27205 0
Java/JDK下载、安装与环境变量配置超详细教程(2022更新)保姆级,秒会
|
8月前
|
人工智能 自然语言处理 程序员
一文彻底搞定从0到1手把手教你本地部署大模型
Ollama 是一个开源工具,旨在简化大型语言模型(LLM)在本地环境的部署与使用。它支持多种预训练模型(如Llama 3、Phi 3等),允许用户根据设备性能选择不同规模的模型,确保高效运行。Ollama 提供了良好的数据隐私保护,所有处理均在本地完成,无需网络连接。安装简便,通过命令行即可轻松管理模型。适用于开发测试、教育研究和个人隐私敏感的内容创作场景。
2703 0
一文彻底搞定从0到1手把手教你本地部署大模型
|
C语言
【C 语言经典100例】C 练习实例40
【C 语言经典100例】C 练习实例40
55 0
|
机器学习/深度学习 图计算
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
|
机器学习/深度学习 人工智能 自然语言处理
利用迁移学习加速AI模型训练
【7月更文第29天】迁移学习是一种强大的技术,允许我们利用已经训练好的模型在新的相关任务上进行快速学习。这种方法不仅可以显著减少训练时间和计算资源的需求,还能提高模型的准确率。本文将详细介绍如何利用迁移学习来加速AI模型的训练,并通过具体的案例研究来展示其在计算机视觉和自然语言处理领域的应用。
333 4
|
SQL Oracle 关系型数据库
CASE WHEN 语句的语法及示例,LeetCode 题目 “确认率” 练习
本文介绍了SQL中CASE语句的两种形式和语法,并通过LeetCode题目“确认率”的SQL查询示例展示了CASE语句在实际问题中的应用,解释了如何使用CASE语句计算特定条件的比率。
|
域名解析 自然语言处理 网络协议
【Python】已解决:nltk.download(‘averaged_perceptron_tagger’) [nltk_data] Error loading averaged_perceptro
【Python】已解决:nltk.download(‘averaged_perceptron_tagger’) [nltk_data] Error loading averaged_perceptro
2155 1
|
数据采集 安全 大数据
使用代理IP时有哪些小技巧?
代理IP工具在大数据和跨境行业广泛使用,能隐藏真实IP并提升数据采集效率。选择时考虑代理IP的质量、速度、稳定性和价格,确保服务商信誉安全。测试多个代理IP以满足不同需求,设置正确请求头信息避免被目标服务器屏蔽。避免频繁更换地区,定期更新代理IP,并保护个人信息。根据业务需求制定使用计划,提前学习相关技巧,可避免后期问题。
|
机器学习/深度学习 自然语言处理 Linux
稀疏微调:彻底改变大语言模型的推理速度
稀疏微调:彻底改变大语言模型的推理速度
624 0