算法刷题打卡第50天:排序数组---快速排序

news2024/11/25 20:26:43

排序数组

难度:中等

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

快速排序

算法介绍:
快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔(Tony Hoare )提出。在平均状况下,排序 n n n 个项目要   O ( n log ⁡ n ) {\displaystyle \ O(n\log n)}  O(nlogn) 次比较。在最坏状况下则需要 O ( n 2 ) {\displaystyle O(n^{2})} O(n2) 次比较,但这种状况并不常见。事实上,快速排序   O ( n log ⁡ n ) {\displaystyle \ O(n\log n)}  O(nlogn) 通常明显比其他演算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的 2 个子序列,然后递归地排序两个子序列。

其基本步骤为:

  1. 挑选基准值:从数列中挑出一个元素,称为“基准”(pivot);
  2. 分割(partition):重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
  3. 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。

思路:
我们定义函数 quicksort(nums, l, r) 为对 nums 数组里 [ l , r ] [l,r] [l,r] 的部分进行排序,如果r-l小于22,则直接进行插入排序。否则每次先调用 partition 函数对 nums 数组里 [ l , r ] [l,r] [l,r] 的部分进行划分,并返回分界值的下标 zoneIndex,然后按上述将的递归调用 quicksort(nums, l, zoneIndex- 1)quicksort(nums, zoneIndex+ 1, r) 即可。

那么核心就是划分函数的实现了,划分函数一开始需要确定一个分界值(我们称之为基准数 pivot),然后再进行划分。而主元的选取有很多种方式,这里我们采用随机的方式,对当前划分区间 [ l , r ] [l,r] [l,r] 里的数等概率随机一个作为我们的基准数,再将基准数放到区间末尾,进行划分。

整个划分函数 p a r t i t i o n partition partition 主要涉及分区指示器 z o n e I n d e x zoneIndex zoneIndex ,一开始 zoneIndex = l - 1
之后依次遍历 n u m s [ l , r ] nums[l,r] nums[l,r]的所有元素,只需要做以下两个判断:

  1. 如果当前元素小于等于基准数时,首先 z o n e I n d e x zoneIndex zoneIndex 右移一位;
  2. 1 1 1 的基础之上,如果当前元素下标大于 z o n e I n d e x zoneIndex zoneIndex 下标时,当前元素和 z o n e I n d e x zoneIndex zoneIndex 所指元素交换。

样例如下:
注意,分区写法不唯一。该动画并没有随机选取基准数,而是使用第一个数作为基准数,并且没有和最后一个位置置换,所以 i i i 是从 l + 1 l+1 l+1 开始遍历,最后遍历完毕将 z o n e I n d e x zoneIndex zoneIndex 的位置和 0 0 0 的位置进行交换,达到分区效果。
请添加图片描述

时间复杂度: 基于随机选取主元的快速排序时间复杂度为期望 O ( n log ⁡ n ) O(n\log n) O(nlogn),其中 n n n 为数组的长度。

空间复杂度: O ( h ) O(h) O(h),其中 h h h 为快速排序递归调用的层数。我们需要额外的 O ( h ) O(h) O(h) 的递归调用的栈空间,由于划分的结果不同导致了快速排序递归调用的层数也会不同,最坏情况下需 O ( n ) O(n) O(n) 的空间,最优情况下每次都平衡,此时整个递归树高度为 log ⁡ n \log n logn,空间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

import random
class Solution:
    # 标准快速排序
    def quicksort(self, nums, l, r):
        # 如果数组长度小于22,则进行插入排序加速,减少递归次数加速排序
        if r - l < 22:
            return self.insertsort(nums, l, r)
        # 获取指示器通过分区后的位置
        zoneIndex = self.partition(nums, l, r)
        # 左右分区分别排序(递归)
        self.quicksort(nums, zoneIndex + 1, r)
        self.quicksort(nums, l, zoneIndex - 1)

    # 快速排序分区
    def partition(self, nums, l, r):
        # 随机选择左右指针中间的一个坐标作为基准数
        pivot = random.randint(l, r)
        nums[pivot], nums[r] = nums[r], nums[pivot]
        # 指示器从 左指针-1 开始
        zoneIndex = l - 1
        # 以下操作的可以节省空间实现原地排序
        for i in range(l, r + 1):
            # 当前元素小于等于基准数
            if nums[i] <= nums[r]:
                # 首先分区指示器进行累加
                zoneIndex += 1
                # 当前元素在分区指示器的右边时,交换当前元素和分区指示器元素
                if zoneIndex < i:
                    nums[zoneIndex], nums[i] = nums[i], nums[zoneIndex]
        return zoneIndex

    # 插入排序
    def insertsort(self, nums, l, r):
        for i in range(l, r + 1):
            index, value = i, nums[i]
            while index > 0 and nums[index-1] > value:
                nums[index] = nums[index-1]
                index -= 1
            nums[index] = value

    def sortArray(self, nums):
        # 为了过最后两个实例...这边就写了标准快排
        if len(set(nums)) == 1:
            return nums
        # 调用快速排序
        self.quicksort(nums, 0, len(nums)-1)
        return nums

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sort-an-array

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

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

相关文章

安科瑞霍尔闭环电流传感器在电动观光旅游车上的应用浅析

摘要&#xff1a; 本文介绍了基于霍尔闭环原理&#xff0c;即磁平衡式原理的电流传感器在电动观光旅游车上的使用方法&#xff0c;替代传统的霍尔器件&#xff0c;较好的解决了电动车行业现有霍尔传感器的基本问题&#xff0c;在稳定性上更加优越。 关键词&#xff1a;霍尔闭…

Linux----tr命令详细使用方法

【原文链接】Linux----tr命令详细使用方法 文章目录一、tr命令使用方法1.1 tr命令的作用1.2 tr命令格式1.3 tr命令常用的选项1.4 常用的匹配字符串二、tr命令常用实例2.1 如何查看文本中的控制字符2.2 将所有小写字母转换为大写字母2.3 将文件中的数字替换为&符号2.4 对命令…

android studio 升级 Dolphin | 2021.3.1 Patch 1 跟 View.isInEditMode,xml无法预览

最近一段时间Google又更新了AS的版本,一些小伙伴尝试了更新,发现在之前版本上好好的xml布局预览,在新版本上不显示了,新版本如下图所示。 一般来说出了新版本之后我们不会马上更新,因为会觉得新版本不稳定,问题多,但其实是问题不大,解决了就好了,那么我现在就遇到了一…

毕业设计 - 基于JSP的超市积分管理系统【源码 + 论文】

文章目录前言一、项目设计1. 模块设计系统功能需求管理员功能柜员功能2. 实现效果二、部分源码项目源码前言 今天学长向大家分享一个 web项目: 基于JSP的超市积分管理系统 一、项目设计 1. 模块设计 系统功能需求 &#xff08;1&#xff09;柜员信息的管理&#xff1a;包括…

交换机端口震荡

交换机端口是支持网络连接和通信的物理网络组件。作为 IT 基础架构的关键部分&#xff0c;它们通过在 OSI 数据链路层转发和接收数据包来促进网络。它们还执行一些关键的网络功能&#xff0c;例如处理第 3 层数据包、创建和管理 VLAN、连接路由器、启用互联网连接等。因此&…

Arweave -- 永久性存储分享

Arweave Arweave 是一种新型存储&#xff0c;它支持具有可持续和永久的数据&#xff0c;允许用户和开发人员真正永久地存储数据 Arweave 项目&#xff0c;以前称为 Archain&#xff0c;正在创建一个与互联网平行的永久、去中心化和不可审查的信息档案。Arweave 的新颖“block…

技术分享 | 软件测试入门必会-流程管理平台

JIRA 是目前比较流行的测试流程管理系统&#xff0c;现在很多大厂使用的都是 JIRA。为什么大厂更爱用 JIRA 呢&#xff1f;其实就是因为它的定制性非常的强。可以自己定义流程&#xff0c;自己定义界面&#xff0c;自己定义字段。通过这些自定义的方式&#xff0c;就可以让整个…

特殊情况的高新技术企业成长性计算方法。

根据文件《高新技术企业认定管理工作指引》&#xff08;国科发火〔2016〕195号&#xff09;规定&#xff0c;选取企业净资产增长率、销售收入增长率等指标对企业成长性进行评价。企业实际经营期不满三年的按实际经营时间计算&#xff0c;计算方法如下&#xff1a; 成长性评分标…

【数据结构初阶】反转链表

文章目录问题描述&#xff1a;思路分析&#xff1a;代码展示&#xff1a;问题描述&#xff1a; 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据…

【计算机毕业设计】79.勤工助学管理系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着我国教育需求不断增加&#xff0c;高校教育资源有限&#xff0c;教育经费相对不足的情况下&#xff0c;利用现代信息技术发展高等教育&#xff0c;不仅充分利用了优秀的教育资源&#xff0c;而且为更多的…

迅为3A5000_7A2000开发板龙芯LoongArch架构

迅为3A5000_7A2000开发板龙芯LoongArch架构 主要参数 处理器: 龙芯3A5000 主频: 2.3GHz-2.5GHz 桥片: 7A2000 内存: 8GB、16GB DDR4带ECC纠错&#xff08;配置可选&#xff09; 系统: Loongnix 典型功耗: 35W 核心板: 16层 底板: 4层 核心板参数 尺寸: 125*95mm CPU: 龙芯…

J-004 Jetson电路设计之HDMI设计--NANO XAVIER NX

HDMI电路设计1 简介2 框图介绍3 原理图介绍1 简介 NANO & XAVIER NX提供一路HDMI接口&#xff0c;DP接口与HDMI是兼容的&#xff0c;可用于扩展一路HDMI。其中引脚说明: PIN名称描述方向类型63HDMI_DP_TXDN0DisplayPort 1 Lane 0 or HDMI Lane 2输出HDMI/DP65HDMI_DP_TXD…

高阶数据结构--图

本篇主要是介绍&#xff1a;图的一些常用的算法。 文章目录 一、图的基本概念二、图的存储结构 1、邻接矩阵2、邻接表三、图的遍历 1、广度优先遍历2、深度优先遍历四、最小生成树 1、Kruskal算法2、Prim算法五、最短路径 1、单源最短路径--Dijkstra算法2、单源最短路径--Bellm…

postgres 源码解析 45 btree分裂流程_bt_split

B树简介 B树一种多路平衡树&#xff0c;有如下特点&#xff1a; m阶B树表示每个节点最多含有m-1个元素&#xff0c;除了根节点之外&#xff0c;每个节点至少含有ceil(m/2)-1个元素。如5阶B树&#xff0c;每个节点最多4个元素&#xff0c;除根节点之外最少含有2个元素&#xf…

Java异常(Exception)处理及常见异常

很多事件并非总是按照人们自己设计意愿顺利发展的&#xff0c;经常出现这样那样的异常情况。 例如&#xff1a; 你计划周末郊游&#xff0c;计划从家里出发→到达目的→游泳→烧烤→回家。 但天有不测风云&#xff0c;当你准备烧烤时候突然天降大雨&#xff0c;只能终止郊游提…

Qt扫盲-QTableWidget理论总结

QTableWidget理论总结1. 概述2. QTableWidgetItem 概述3. 表头设置4. 常用功能5. 常用信号6. 槽函数7. 外观1. 概述 QTableWidget 是 Qt 提供的一个简单方便、标准的表格显示类。QTableWidget 中的 单元格数据 由 QTableWidgetItem 显示如果 想要一个使用你自己定义modle 的表…

MR案例(3):计算学生成绩(总分和平均分)

文章目录一、 任务目标1. 准备数据二、实行任务1. 创建Maven项目2. 添加相关依赖3. 创建日志属性文件4. 创建成绩映射器类5. 创建成绩驱动器类6. 启动成绩驱动器类&#xff0c;查看结果7. 创建成绩归并器类8. 修改成绩驱动器类9. 启动成绩驱动器列&#xff0c;查看结果一、 任务…

艾美捷利妥昔单抗Rituximab参数及应用

艾美捷利妥昔单抗Rituximab背景&#xff1a; 利妥昔单抗是一种针对CD20抗原的基因工程嵌合鼠/人单克隆IgG1κ抗体。利妥昔单抗的分子量约为145 kD。利妥昔单抗由哺乳动物细胞&#xff08;中国仓鼠卵巢&#xff09;产生。 艾美捷利妥昔单抗Rituximab基本参数&#xff1a; 中文…

Java+SSM流浪猫狗救助领养网站(含源码+论文+答辩PPT等)

项目功能简介: 该项目采用技术&#xff1a; 后端采用SSM框架 前端采用了htmlcssbootstrap框架 MySQL数据库Tomcat服务器&#xff0c;项目含有源码、文档、配套开发软件、软件安装教程、项目发布教程等 项目功能介绍&#xff1a; 项目分为前端和后端两&#xff0c;包含的功能主要…

DBCO-PEG-TPP,二苯并环辛炔-聚乙二醇-磷酸三苯酯,DBCO-PEG磷酸三苯酯

【产品描述】 西安凯新生物科技有限公司供应的&#xff1a;​DBCO-PEG-TPP亲水性聚乙二醇 (PEG) 间隔臂提供了一个长而灵活的连接&#xff0c;磷酸三苯酯为无味、无臭的白色结晶块状或粉末&#xff0c;它不溶于冷水,但可溶于50℃以上的热水中,当溶液温度降低至室温时呈现疏水性…