leetcodeT912-快排优化-三路划分

2023-10-14 01:45

本文主要是介绍leetcodeT912-快排优化-三路划分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

leetcodeT912-快排优化-三路划分

  • 1.前言
  • 2.为什么需要三路划分的优化?
  • 3.三路划分的思想及举例画图
  • 4.三路划分的代码实现
  • 5.三数取中修改

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

这篇关于leetcodeT912-快排优化-三路划分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/207282

相关文章

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

MySQL中慢SQL优化方法的完整指南

《MySQL中慢SQL优化方法的完整指南》当数据库响应时间超过500ms时,系统将面临三大灾难链式反应,所以本文将为大家介绍一下MySQL中慢SQL优化的常用方法,有需要的小伙伴可以了解下... 目录一、慢SQL的致命影响二、精准定位问题SQL1. 启用慢查询日志2. 诊断黄金三件套三、六大核心优化方案方案