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针对快排的三路划分优化的讲解,希望能对大家有所帮助!

目录
打赏
0
0
0
0
4
分享
相关文章
使用Node.js访问API的示例
下面是一个使用Node.js访问API的示例代码:
210 1
Java/JDK下载、安装与环境变量配置超详细教程(2022更新)保姆级,秒会
Java/JDK下载、安装与环境配置超详细教程(2022更新)保姆级,小白秒会[学习必备,建议收藏]。包含JDK8、JDK11、JDK17、JDK19等,本文将从JDK的下载与安装讲起,在从配置到第一个HelloWrold实践结束。在观看本文前我们需要知道JDK是什么,有什么作用?JDK是Java的开发工具包,包括JVM虚拟机,核心类库,开发工具。
26200 0
Java/JDK下载、安装与环境变量配置超详细教程(2022更新)保姆级,秒会
【C 语言经典100例】C 练习实例40
【C 语言经典100例】C 练习实例40
44 0
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
利用迁移学习加速AI模型训练
【7月更文第29天】迁移学习是一种强大的技术,允许我们利用已经训练好的模型在新的相关任务上进行快速学习。这种方法不仅可以显著减少训练时间和计算资源的需求,还能提高模型的准确率。本文将详细介绍如何利用迁移学习来加速AI模型的训练,并通过具体的案例研究来展示其在计算机视觉和自然语言处理领域的应用。
267 4
【Python】已解决:nltk.download(‘averaged_perceptron_tagger’) [nltk_data] Error loading averaged_perceptro
【Python】已解决:nltk.download(‘averaged_perceptron_tagger’) [nltk_data] Error loading averaged_perceptro
1885 1
基于ssm+vue.js+uniapp小程序的建筑装修图纸管理平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的建筑装修图纸管理平台附带文章和源代码部署视频讲解等
117 0
使用代理IP时有哪些小技巧?
代理IP工具在大数据和跨境行业广泛使用,能隐藏真实IP并提升数据采集效率。选择时考虑代理IP的质量、速度、稳定性和价格,确保服务商信誉安全。测试多个代理IP以满足不同需求,设置正确请求头信息避免被目标服务器屏蔽。避免频繁更换地区,定期更新代理IP,并保护个人信息。根据业务需求制定使用计划,提前学习相关技巧,可避免后期问题。
(详解踩坑)GIT版本回滚git stash、git reset、git reset --hard、git revert
(详解踩坑)GIT版本回滚git stash、git reset、git reset --hard、git revert
1415 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等