算法——分治(快速排序)

在这里插入图片描述

T04BF

👋专栏: 算法|JAVA|MySQL|C语言

🫵 小比特 大梦想

此篇文章与大家分享分治算法关于快速排序的专题
对于快速排序在我个人主页专栏 <排序> 有详细的介绍,此专题对快排进行了优化操作,并介绍了优化后的快排的几种运用
如果有不足的或者错误的请您指出!

1.颜色分类

题目:颜色分类

1.1解析

这道题目实际上就是将一个给定的只有0,1,2的数组,分成三块,0放在一起,1放在一起,2放在一起

回顾一下移动0问题,实则就是利用双指针将数组划分为两部分.本题也可以利用类似的思想,只不过是将数组划分为3部分

在这里插入图片描述
如图所示,我们标记好left和right,用i来遍历数组,那么这三个变量实际上就将数组划分为4个区间,而我们要做的就是在遍历数组的时候去维护三个区间就好了

(1)arr[i] == 0

为了维护0都在[0,left]这段区间,那么我们要让交换arr[++left]和arr[i],后i++继续遍历

(2)arr[i] == 1

为了维护1都在[left+1,i]这段区间,我们只需让i++即可

(3)arr[i] == 2

为了维护2都在[right,n-1(n为数组长度)],我们要让arr[–right]和arr[i]交换,但是此时i不能++,因为此时从[right,n-1]交换过来的元素还没判断

维护好这三个区间,当i与right相遇即可

class Solution {public void sortColors(int[] arr) {int left = -1;int n = arr.length;int right = n;for(int i = 0; i < right; ){if(arr[i] == 0){swap(arr,i++,++left);}else if(arr[i] == 1){i++;}else{swap(arr,i,--right);}}}public void swap(int[] array,int i,int j){int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}

2.利用数组划分实现快速排序

题目:数组排序

2.1解析

我们之前学过的快速排序是每次把数组划分为两部分,时间复杂度最好情况下为O(NlogN),但是如果出现大部分的相同元素,就会大大增加时间复杂度

在本题中,我们对之前学过的快速排序进行优化

(1)跟上一题颜色划分一样,在找定基准元素key后,我们把区间每次都分成三部分,

在这里插入图片描述

这样做的好处是,我们再次对不同区间进行递归的时候,就不必再考虑中间 == key 的部分了,因为中间都是相同的值,就没必要参与排序了

而分区域的思想在上一道颜色划分的题目已经讲过

实际上就是用i来遍历区间的时候,分三种情况:(推导过程在上一道题已经演示)

①nums[i] < key => swap(i++,++left)

②nums[i] == key => i++

③nums[i] > key => swap(i,–right)

(2)基准元素

我们在之前讲过的快速排序中,基准元素要么是端点值,要么是利用三数取中,但是最优秀的解法应该是等概率的随机在区间里面找基准元素

那么我们就可以利用随机数的方式,即在区间范围内产生随机数下标 random.nextInt(R-L+1)+L

2.2题解

class Solution {public int[] sortArray(int[] nums) {qsort(nums,0,nums.length-1);return nums;}private void qsort(int[] nums,int l,int r){if(l >= r){return;}Random random = new Random();int key = nums[random.nextInt(r-l+1)+l];int left = l-1;int right = r+1;int i = l;while(i < right){if(nums[i] < key){swap(nums,i++,++left);}else if(nums[i] == key){i++;}else{swap(nums,i,--right);}}qsort(nums,l,left);qsort(nums,right,r);}private void swap(int[] nums,int i,int j){int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}
}

3.快速选择算法

题目:第k个最大的数

3.1解析

此题实际上是我们快排优化版的运用

在这里插入图片描述

我们在上一题的快速排序中把区间划分为如图所示的三部分,我们分别用a,b,c来表示三部分各自元素个数,那么对于要找的第k个最大元素,就会出现三种情况

(1) c >= k

说明第k个最大元素就是 在c区间的第k个最大元素,那么我们就直接针对c区间进行递归即可,a,b区间不用管

(2)在c >= k 不成立的前提下,如果b + c >= k,那么说明第k个最大元素一定在b区间,而b区间全部都是相同元素,那么直接返回key即可

(2)在前面两个条件都不成立的情况下,那么第k个最大元素只能在a区间,那么我们就要去a区间递归,但是此时就不是找第k个最大元素了

在这里插入图片描述

此时由于大元素都在后面,而我们仅仅只是针对a区间寻找,前k个最大元素有b+c个是在b ,c区间里面的,因此我们要在a中寻找的是第k-b-c大的元素

3.2题解

class Solution {public int findKthLargest(int[] nums, int k) {return qSort(nums,k,0,nums.length-1);}private int qSort(int[] nums,int k, int l,int r){//此时由于下面已经分类讨论了,因此不可能出现无意义区间的情况int key = nums[new Random().nextInt(r-l+1)+l];int left = l-1;int right = r+1;int i = l;while(i < right){if(nums[i] < key){swap(nums,i++,++left);}else if(nums[i] == key){i++;}else{swap(nums,i,--right);}} //三个区间为[l,left] [left+1,right-1] [right,r]int b = right - left - 1;int c = r - right + 1;if(c >= k){return qSort(nums,k,right,r);}else if(b + c >= k){return key;}else{return qSort(nums,k-b-c,l,left);}}private void swap(int[] nums,int i,int j){int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}
}

4.最小的k个数

题目:最小的k个数

4.1解析

我们一开始想到的方法可能就是直接排序,然后返回前k个最小的数

但是题目对于返回的数组里面的元素是否有序并不关心

在这里插入图片描述

我们在上面的快排中将区间分成三部分,那么对于最小的前k个元素,也会出现三种情况

(1)a > k,那么最小的前k个元素就都在a区间,我们直接去a区间递归即可

(2)在a > k不成立的前提下,如果a + b >= k,那么说明此时最小的前k个元素分成两部分,一部分在a区间,一部分在b区间,由于不关心返回数组里面元素是否有序,那么我们直接返回此时数组的前k个元素即可

(3)在前面两种情况都不满足的前提下,说明此时最小的前k个元素,一部分是a+b的所有元素,一部分是c里面的元素,那么我们就要去c里面递归寻找第k-a-b个元素

4.2题解

class Solution {public int[] inventoryManagement(int[] stock, int cnt) {qSort(stock,cnt,0,stock.length-1);int[] ret = new int[cnt];for(int i = 0; i < cnt; i++){ret[i] = stock[i];}return ret;}private void qSort(int[] stock,int cnt,int l,int r){int key = stock[new Random().nextInt(r-l+1)+l];int left = l-1;int right = r+1;int i = l;while(i < right){if(stock[i] < key){swap(stock,i++,++left);}else if(stock[i] == key){i++;}else{swap(stock,i,--right);}}//[l,left] [left+1,right-1] [right,r]int a = left - l + 1;int b = right - left - 1;if(a > cnt){qSort(stock,cnt,l,left);}else if(a + b >= cnt){return;}else{qSort(stock,cnt-a-b,right,r);}}private void swap(int[] nums,int i,int j){int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}
}

感谢您的访问!!期待您的关注!!!

在这里插入图片描述

T04BF

🫵 小比特 大梦想

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/793793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【正点原子探索者STM32F4】TFTLCD实验学习记录:FSMC控制 TFTLCD的寄存器配置

FSMC控制 TFTLCD的寄存器配置 异步模式 A控制 TFTLCDFSMC寄存器配置ILI9341电平持续时间要求 参考 异步模式 A控制 TFTLCD LCD以ILI9341为例 FSMC寄存器配置 对于异步突发访问方式&#xff0c; FSMC 主要设置 3 个时间参数&#xff1a;地址建立时间(ADDSET)、 数据 建立时间…

Unity之PUN实现多人联机射击游戏的优化(Section 2)

目录 &#x1f3ae;一、准备工作 &#x1f3ae;二、实现手雷投掷动作 &#x1f3ae;三、手雷投掷同步 &#x1f4a4;3.1 photonView.RPC &#x1f3ae;四、同步手雷伤害 这几周都给我布置任务了&#xff0c;最近可忙。现在终于有机会更新了&#xff0c;也谢谢大家的阅读&a…

JavaSE-11笔记【多线程2(+2024新)】

文章目录 6.线程安全6.1 线程安全问题6.2 线程同步机制6.3 关于线程同步的面试题6.3.1 版本16.3.2 版本26.3.3 版本36.3.4 版本4 7.死锁7.1 多线程卖票问题 8.线程通信8.1 wait()和sleep的区别&#xff1f;8.2 两个线程交替输出8.3 三个线程交替输出8.4 线程通信-生产者和消费者…

Tailwind 4.0 即将到来:前端开发的“速度与激情”

随着前端开发技术的不断进步&#xff0c;我们每天都在寻找更快、更简洁的解决方案来提升我们的开发效率和用户体验。今天&#xff0c;我要为大家介绍一项令人振奋的新技术进展——Tailwind 4.0的来临&#xff01; 对于经常使用Tailwind的朋友们来说&#xff0c;这个消息无疑是激…

阿里云短信服务业务

一、了解阿里云用户权限操作 1.注册账号、实名认证&#xff1b; 2.使用AccessKey 步骤一 点击头像&#xff0c;权限安全的AccessKey 步骤二 设置子用户AccessKey 步骤三 添加用户组和用户 步骤四 添加用户组记得绑定短信服务权限 步骤五 添加用户记得勾选openApi访问 添加…

Educational Codeforces Round 162 (Rated for Div. 2) ----- E. Count Paths --- 题解

E. Count Paths&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 根据题目中定义的美丽路径&#xff0c;我们可以发现路径只有两种情况&#xff1a; 当前结点作为起始结点&#xff0c;那我们只需要知道它的子树下有多少个相同颜色的结点&#xff0c;并且相同颜色的结…

使用 HTMX 和 Bun 进行全栈 Web 开发

将 HTMX 放在前端&#xff0c;Bun 放在后端&#xff0c;然后将它们与 Elysia 和 MongoDB 连接起来&#xff0c;形成快速便捷的技术栈&#xff0c;使开发 Web 应用程序变得轻而易举。 Bun 和 HTMX 是目前软件领域最有趣的两个事情。 Bun 是一个速度极快的一体化服务器端 JavaSc…

如何创建一个TCP多人聊天室?

一、什么是TCP&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;是一种可靠的 面向连接的协议 &#xff0c;可以保证数据在传输过程中不会丢失、重复或乱序。 利用TCP实现简单聊天程序&#xff0c;需要客户端和服务器端之间建立TCP连接&#xff0c;并通…

MATLAB近红外光谱分析技术应用

郁磊副教授&#xff0c;主要从事MATLAB编程、机器学习与数据挖掘、数据可视化和软件开发、生理系统建模与仿真、生物医学信号处理&#xff0c;具有丰富的实战应用经验&#xff0c;主编《MATLAB智能算法30个案例分析》、《MATLAB神经网络43个案例分析》相关著作。已发表多篇高水…

C# MES通信从入门到精通(8)——C#调用Webservice服务进行数据交互

前言 在上位机开发领域,使用webservice来访问客户的终端Mes系统是一项必备的技能,本文详细介绍了如何在c#中调用webservice服务,不仅介绍了使用添加服务引用直接调用webservice中的方法外还介绍了使用http的post方法调用webservice方法,过程详细且均为实战经验总结,对于初…

港口核心!达梦数据助力上港集团罗泾码头 I-TOS 系统升级改造

港口作为交通运输的枢纽和联通世界的窗口&#xff0c;肩负着带动区域经济发展及服务国际经贸的双重责任。在信息化浪潮推动下&#xff0c;自动化、数字化、智能化成为港口航运业转型发展的关键。 达梦数据积极推进港口数字化转型升级 &#xff0c;助力上港集团罗泾码头实现 I-T…

青蛙过河(二分+前缀和)

题目描述 小青蛙住在一条河边&#xff0c;它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。 河里的石头排成了一条直线&#xff0c;小青蛙每次跳跃必须落在一块石头或者岸上。不过&#xff0c;每块石头有一个高度&#xff0c;每次小青蛙从一块石头起跳&#xf…

[问题记录] oracle问题汇总记录

plsql问题 1、oracle-initialization error could not locate OCI.dll 下载plsql客户端后&#xff0c;登录显示如图所示的错误 解决方法&#xff0c;点击下方链接&#xff0c;下载64位客户端 Instant Client for Microsoft Windows (x64) 64-bit (oracle.com) 2、显示中文乱…

【资源分享】最全ChatGPT镜像免梯子

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

leetCode第十题 : 正则表达式匹配 动态规划【10/1000 python】

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

wordpress全站开发指南-面向开发者及深度用户(全中文实操)--初尝php

初尝php 打开你下载的wordpress文件夹&#xff0c;如果你用的xampp那它就在xampp安装的文件夹–htdocs文件夹–你可以新建一个test文件夹–新建一个test.php文件 <html><head><title>First attempt at PHP</title></head><body><?ph…

Spring注解开发和XML开发

目录 Spring简介发展史Spring Framework系统架构spring 核心概念IOC、IOC容器、Bean、DIIOC快速入门DI快速入门 IOCBean基础配置id与class属性name属性scope属性 Bean的实例化构造方法静态工厂实例工厂FactoryBean的使用&#xff08;工厂实例的简化&#xff09; Bean的生命周期…

【Qt】:常用控件(三:按钮类)

常用控件&#xff08;三&#xff09; 一.Push Button二.Radio Buttion三.Check Box 一.Push Button 使⽤ QPushButton 表⽰⼀个按钮.这也是当前我们最熟悉的⼀个控件了.QPushButton继承⾃QAbstractButton .这个类是⼀个抽象类.是其他按钮的⽗类. QAbstractButton 中,和 QPushBu…

Qt中出现中文乱码的原因以及解决方法

Qt专栏&#xff1a;http://t.csdnimg.cn/C2SDN 目录 1.引言 2.原因分析 3.源文件的编码格式修改方法 4.程序内部使用的默认编码格式修改方法 5.QString转std::string的方法 6.总结 1.引言 在编写Qt程序的时候&#xff0c;或多或少都可能遇到用QString时候&#xff0c;明明…

Docker 安装 | 部署MySQL 8.x 初始设置

1、准备工作 如果不想看前面的废话请直接右边目录跳到 运行容器 处 默认你已经有 docker 环境。 Windows 推荐 Docker Desktop &#xff08;下载地址&#xff09;并基于 WSL2 运行 Docker 环境 mac 推荐 Orbstack &#xff08;下载地址&#xff09;&#xff08;这个很节省资源&…