当前位置: 首页 > news >正文

优选算法——分治(1):三路快排

🔥近津薪荼: [个人主页]
🎬个人专栏: 《近津薪荼的算法日迹》
《Linux操作系统及网络基础知识分享》
《c++基础知识详解》
《c语言基础知识详解》
✨不要物化,矮化,弱化,钝化自己,保持锋芒,不要停止学习
这个世界上只有两个人真正在注意着你
八岁的你,和八十岁的你,
他们此刻正在注视着你,
一个希望你勇敢开始,一个希望你不留遗憾

1.上期参考代码

classSolution{public:vector<int>missingTwo(vector<int>&nums){inttmp=0;for(inti=0;i<nums.size();i++){tmp^=nums[i];}for(inti=1;i<=nums.size()+2;i++){tmp^=i;}//此时tmp已经等于a^bintpos=0;while(1){if(tmp&(1<<pos))break;elsepos++;}inta=0;for(inti=0;i<nums.size();i++)if(nums[i]&(1<<pos))a^=nums[i];for(inti=1;i<=nums.size()+2;i++)if(i&(1<<pos))a^=i;tmp^=a;return{a,tmp};}};

2.本期知识点导图

3.本期要讲解的题目是

排序数组

要点:

戳这里跳转到这个博主的讲解

了解一下基本的算法思想,有递归基础,学起来也快。

4.解题

4.1 快排

代码如下:

classSolution{public:vector<int>sortArray(vector<int>&nums){qsort(nums,0,nums.size()-1);returnnums;}voidqsort(vector<int>&nums,intleft,intright){if(left>=right)return;intkey=(left+right)/2;intmid=nums[key];intl=left-1,r=right+1;while(l<r){dol++;while(nums[l]<mid);dor--;while(nums[r]>mid);if(l<r)swap(nums[l],nums[r]);}qsort(nums,left,r);qsort(nums,r+1,right);}};

这个代码也能过,但是我们分析其时间复杂度,即普通快排的时间复杂度

普通快排的平均(随机)时间复杂度是O(NlogN)
最差情况即每次分区都把数组拆成「长度为 n−1 和 0/1 的两部分」(极端不平衡),递归层数是 n,每层处理需要 O(n),总复杂度 O(n 2 )。

4.2三路快排

快排算法中,递归的每一层,我们是找一个值key,将数组分成两部分:值小于key,值大于key;

提到数组分块,不知到大家还有没有印象,我们在讲双指针的时候,第一道题就是数组分块:移动0(点击跳转)

两个指针,数组分成3块:未处理,已处理0,已处理非零,right不断向后遍历,left不断维护已处理部分的信息

双指针的好处就是通过指针遍历时的不回退性质,将遍历的的时间复杂度降至O(N),但是这里并没有降幅时间复杂度,因为普通快排中也是通过不回退的双指针来遍历数组的。

区别:

三路快排,将数组分成了三个部分,相对于普通快排,当数组中存在大量重复元素的时候,使用这个三路快排,减少大量的遍历操作,仅仅推进i的向后遍历即可。视觉上呈现的效果应该是中间的区间越来越大,下次递归传入的区间越来越小,那么下次需要遍历的区间也会减小~,所以我们可以根据数据的特征来选择使用哪个快排。

关键思路:

我们观察快排中每一层递归做的事,其实就是将数组按照<k,=k,>k来分块,然后在这一层结束之前,还有第4块,也就是未处理的部分。

这样子就能把知识点串起来了~~快哉


与双指针算法类似,我们搞一个“三指针”,将数组分成4块:

在遍历的过程中,数组分块分布如上图

各参数和指针的作用:

注意:维护“>”区间的时候,与nums[i[交换的元素,也就是当前i位置的元素也是未处理的,与维护"<"区间的时候不同。

整体代码逻辑就是推动i遍历数组,维护好3个区间部分

5.下期要讲解的题目是:

数组中的第K个最大元素

6.嗟食

如果小编写的内容对佬有帮助,还请大佬点点三连加关注哦
佬的支持就是我前进的最大动力~

期待与佬的再次相遇~

http://www.jsqmd.com/news/459358/

相关文章:

  • 【更新至2024年】2013-2024年各省数字经济指数数据(含原始数据+计算代码+结果)
  • 1分钟,带你认识门窗五金系统!
  • Ubuntu 20.04 LTS 防止暴力破解
  • Unreal Engine 4核心概念解析:Pawn——游戏世界中的可操控化身
  • Methyltetrazine–PEG4–Mal 1802908-02-6 活细胞双靶点标记探针
  • 基于Simulink的鲁棒H∞整流器控制器设计
  • 【通俗易懂告诉你什么是人工智能/CNN/RNN/DL......】
  • 智能AI裂缝识别 裂缝图像分割识别 建筑物裂缝识别 建筑结构裂缝自动检测模型训练 道路桥梁病害识别算法10529期
  • Unreal Engine 4核心概念解析:Character——专为人形角色设计的终极“游戏化身”
  • 毕业设计:基于SpringBoot Ai和Vue的旅游攻略小程序(源码)
  • OpenClaw霸榜,Agent正悄无声息地干掉传统“App”!
  • Mac病毒清除过程, SimulatorTrampoline,提醒事项APP伪装 XcodeGhost,XCSSET类型
  • 刷题笔记:力扣第18题-四数之和
  • 华为 MetaERP 的内部交易协同,是基于元数据驱动的多组织模型 + 事件驱动的服务总线 + 分布式事务 + 智能对账引擎,实现内部交易从发起、协同、确认到对账、抵消的全链路自动化、数据同源、零差异
  • STM32CubeMX配置串口采集超声波传感器数据(四)
  • Android BLE 稳定连接管理器(Kotlin版)完整代码骨架(下篇)
  • 动态规划之背包问题详解(从入门到实战)
  • Kubernetes中的网络策略(Network Policies)
  • 华为 MetaERP 已成为核电行业国产替代的核心方案,以全栈自主可控为基础,通过联合共建模式深度适配核电高安全、强管控、长周期的行业特性,已在中核、中广核等龙头企业落地标杆项目
  • SAP(以 S/4HANA 为代表)通过多组织建模、多分类账(多账套)、多币种引擎、多会计准则并行四大核心机制,在统一数据模型(ACDOCA)上实现集团化、全球化、多准则的财务核算架构
  • 3.5 数据管线、损失函数与分布式训练如何配合
  • Python 源文件默认编码是 **UTF-8**(推荐使用),如果文件包含非 ASCII 字符(如中文),无需额外声明;若需使用其他编码(如 GBK),需在文件第一行/第二行声明
  • SAP 利润中心Profit是如何实现跨法人、穿透式管理的?
  • 基于堆叠自动编码器(SAE)的人脸图像识别:Matlab 实现
  • 第10章 移动平台着色器优化实战:从简化到高级技巧
  • schoober-ai-sdk:核心ReAct 引擎的实现
  • SAP 利润中心 + 分部报告 + 集团合并 + 多准则 是怎么联动成一套集团财务架构的
  • 基于 CAN 总线的 DSP280049C 升级方案全解析
  • OpenClaw Mac本地部署保姆级教程:手把手教你“养龙虾”
  • 不是烤串故事【牛客tracker 每日一题】