LeetCode—1.快速排序算法_leetcode中的快速排序-程序员宅基地

技术标签: LeetCode刷题  快速排序算法  

1.基本思想

  快速排序算法(Quick Sort)是冒泡算法的一种改进,是一种不稳定的排序算法。其主要思想是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据要比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,最终整个数据变成了有序序列。

冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换。
冒泡排序算法的运作如下:
1.比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

2.算法原理

  快速排序算法运作如下:

  1. 从数列中挑出一个元素,称为基准(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。分区操作结束之后,基准元素就处于最终排序后它的位置。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序,直至所有子数列只剩下一个元素为止

3.分区—partition

  以下两种方法掌握其一就行

1.挖坑法

在这里插入图片描述

在开始的时候4,1下面都有指针,分别对应的l、r指针,第一个坑为4,由于r指针指向的1小于4,所以1移到l指针指向的坑,此时原1出处为坑,l指针向右移动一位,指向7,由于l指针指向的7大于4,所以7移动到l指针指向的坑,此时原7处为坑,重复该操作直到l指针与r指针相重合,此时该处就为4.
以上就完成了分区操作,
接下来再递归地把小于基准值元素的子数列和大于基准值元素的子数列排序,直至所有子数列只剩下一个元素为止

2.指针交换法

  核心思想就是找到两边不满足条件的指针然后交换指针。
在这里插入图片描述

基准为4,l指针指向7,r指针指向1,由于1<4<7,不满足条件,所以两个指针交换,r指针移动一位,1<4<8,满足条件,r指针移动一位,1<4<2右边不满足条件,需移动左边,l指针移动一位,6<4<2,两边均不满足条件,两个指针交换,r指针移动一位,2<4<3,右边不满足条件,l指针移动一位,5<4<3,两个指针交换,r指针向左移动一位,此时双指针重合并指向3,3与4对调。
以上便是指针交换法。

4.怎么选取基准

  1. 选取第一个元素作为基准
  2. 随机选择一个元素作为基准

5.时间复杂度

  快速排序的平均时间复杂度是O(nlogn),最坏情况下的时间复杂度是O(n^2)。

选取第一个元素作为基准时,n个元素,每个元素遍历一次,此时,时间复杂度为O(n^2)

6.LeetCode

  215.在未排序的数组中找到第k个最大的元素(需要找的是数组排序后第k个最大的元素)

输入:[3,2,1,5,6,4]和k
输出:5

class Solution:
    def findKthElement(self, nums, k):
        '''
        找到数组中第k个最大元素,
        快速排序每一轮确定一个位置,如果我们想要的位置的元素确定了,那么排序就结束了
        :param nums: 数组
        :param k: k
        :return: 返回第k个最大元素
        '''
        return self.quickSort(nums, k)

    def quickSort(self, nums, k):
        # 找到我们要寻找元素的位置
        k = len(nums) - k
        # 左右指针的位置
        left, right = 0, len(nums) - 1  # 0,4
        while left < right:
            # 进行分区操作,得到确定的位置,将确定的位置与k进行比较后,对子数据集进行分区操作
            j = self.partition(nums, left, right)
            if j == k:
                break
            elif j < k:
                left = j + 1
            else:
                right = j - 1
        # 跳出循环有两个条件:一种是j=k,一种是left=right,两种情况下均可满足j=k
        return nums[k]

    def partition(self, nums, left, right):
        '''
        分区操作—挖坑法,确定某个元素的位置
        :param nums: 数组
        :param left: 左指针
        :param right: 右指针
        :return: 返回确定元素的位置
        '''
        pivot = nums[left]
        # quickSort函数中也有left、right函数
        i, j = left, right
        # 跳出循环的条件是:i = j,此时,即为元素的位置
        while i < j:
            # 跳出条件是找到小于基准的元素nums[j]或i=j
            while i < j and nums[j] > pivot:
                j -= 1
            if i < j:
                nums[i] = nums[j]
                i += 1

            # 找到大于基准的元素nums[i]
            while i < j and nums[i] <= pivot:
                i += 1
            if i < j:
                nums[j] = nums[i]
                j -= 1
        # i = j时
        nums[i] = pivot
        return i


def main():
    nums = [3, 2, 1, 5, 6, 4]
    k = 2
    s = Solution()
    kth_element = s.findKthElement(nums, k)
    print('数组中第%d个最大元素为%d' % (k, kth_element))


if __name__ == '__main__':
    main()

代码已上传至https://github.com/Libra-1023/leetcode

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46649052/article/details/114296843

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签