首页
学习
活动
专区
圈层
工具
发布

美团面试:请手写一个快排,被我怼了!

今天,这个题目是当时面试官叫我现场手写快排,场景如下: 面试官:我们继续来聊聊关于数据结构与算法,你能写一个快速排序?...核心思想: 先从数列中取出一个数作为基准数,然后进行大小分区; 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边; 再对左右区间重复第二步,直到各区间只有一个数,排序完成。...4.复杂度分析 时间复杂度: 最坏情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序) 这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n...快速排序法总结 默认取第一个元素为轴心点(轴心点的确认区分了 “快速排序法”和“随机排序法”)两种算法,而随机排序则随机rand一个元素为轴心点; 如果两个不相邻元素交换,可以一次交换消除多个逆序,加快排序进程...后记 最后再说说,其实你觉得快速排序在工作中有用吗?工作近十年的我真的没用过,但我知道这个快排的思路。如果面试前不准备,我反正是肯定写不出来的,你呢? 学习算法,收获有两个:思维开发和应付面试。

70620

C++经典算法题-快速排序法(一)

37.Algorithm Gossip: 快速排序法(一) 说明 快速排序法(quick sort)是目前所公认最快的排序方法之一(视解题的对象而定),虽然快速排序法在最差状况下可以达O(n2),但是在多数的情况下...快速排序法的基本精神是在数列中找出适当的轴心,然后将数列一分为二,分别对左边与右边数列进行排序,而影响快速排序法效率的正是轴心的选择。...这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解, 也最符合轴心分割与左右进行排序的概念,适合对初学者进行讲解。...解法 这边所介绍的快速演算如下:将最左边的数设定为轴,并记录其值为 s 廻圈处理: 令索引 i 从数列左方往右方找,直到找到大于 s 的数令索引 j 从数列左右方往左方找,直到找到小于 s 的数如果...i >= j,则离开回圈 如果 i 的值将左侧的轴与 j 进行交换 对轴左边进行递回对轴右边进行递回 透过以下演算法,则轴左边的值都会小于s,轴右边的值都会大于s,如此再对轴左右两边进行递回

61510
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【数据结构】排序算法系列——快速排序(附源码+图解)

    ,右边比其大 递归重复此步骤,注意基准值不能重复,直到完全有序 具体的动画分析可以看这:快速排序算法动画演示_哔哩哔哩_bilibili 我们首先来对基准值的选择进行分析: 通常我们都会选择最左边或者最右边的基准值...我们知道最左边和最右边的数有可能是整个数据组中最大或者最小的数,而一轮快速排序的最终目的就是使用基准值将数据分为比其大和比其小的两部分,那么如果记住基准值本身就是一个最值,排序完之后必定也只会在最前或者最后一个位置...如果我们需要规避这种最坏的情况,我们可以使用随机基准值或者三数取中法。这样能够有效规避最坏情况的发生,但并非绝对事件。...这也是它分区交换排序名字的由来。分析分区原理,只要一直不断地进行分区操作,那么最后每个数都可以成为一次基准值,也就可以达到每个数的左边都比其小,右边都比其大,那么整体来看就已经实现了完全有序。...移动指针: 左指针向右移动,直到找到一个大于等于基准值的元素。 右指针向左移动,直到找到一个小于等于基准值的元素。

    27910

    【优选算法篇】分治策略,速战速决:快速选择排序的神奇之处(下篇)

    1.2 快速选择排序(Quick Select)算法的核心思想: 快速选择排序(Quick Select)是一种基于快速排序思想的选择算法,它用于找到数组中的第 k 小元素,而不是对数组进行完全排序。...1.4 快速选择排序的优势和重要性: 时间复杂度: 快速选择排序的平均时间复杂度为 O(n),而最坏情况为 O(n²)(类似于快速排序),但通过三数取中法或随机选择枢纽,可以大大降低最坏情况发生的概率...1.5 快速选择排序的核心思想: 快速选择排序的核心思想是在分治法框架下进行快速查找第 k 小元素,步骤包括: 选择枢纽(Pivot): 选择一个枢纽元素,可以使用三数取中法来避免极端情况。...if (l == r):如果子数组只包含一个元素,直接返回该元素。 随机选择一个基准元素 key,并使用三路分区法(类似于快速排序)将数组分为三个部分:小于基准、大于基准和等于基准。...算法利用随机化技术避免了最坏情况,并通过分治策略将时间复杂度保持在 O(n)(平均情况下),非常适合大规模数据的处理。

    38010

    【数据结构与算法】快速排序万字全攻略:hoare版本、挖坑法、前后指针法、优化版、非递归实现

    找到后,将该元素的值放到end指针所指的“坑”中(注意,此时end已经向左移动过,所以不会覆盖之前放置的值)。 这个过程会一直进行,直到begin和end相遇或交错。...为了改善最坏情况的表现,可以采取三数取中法来优化。 快速排序三数取中法(也称为三数中值分割法)是快速排序算法的一种优化策略,它旨在通过更合理地选择分区点来减少算法在极端情况下的性能退化。...在极端情况下,如果分区点总是选择到数组的最小值或最大值,那么每次分区都将导致一个空子数组和一个几乎不变的子数组,从而使得算法的时间复杂度退化为O(n^2)。...最坏情况(O(n^2)): 当数组已经有序或几乎有序,且分区点总是选择到数组的最小值或最大值时,快速排序的性能会退化到O(n^2)。...虽然存在最坏情况的风险,但通过随机选择分区点或使用三数取中等策略,可以大大降低遇到最坏情况的可能性。

    51310

    Python快速排序算法原理及实现

    1 问题 在Python中如果不使用sort()等类似的排序函数,但是想对一个数组进行排序,该如何实现? 2 方法 可以使用快速排序(Quick Sort)算法解决上述问题。...快排的时间复杂度达到了O(nlogn),在大数据集的情况下具有很高的效率。 快速排序的基本原理是:选择一个基准元素,将数组中小于它的元素移动到它的左边,大于它的元素移动到它的右边。...然后将左右两个子数组再进行同样的操作,直到排序完成。 实现步骤: 选择基准元素。 通常情况下可以选择第一个或最后一个元素。...代码清单 1 #定义一个名为“main”的函数,该函数以数字列表作为输入def main(nums): #如果列表的长度小于或等于1,则按原样返回列表(基本情况) if len(nums)...选择列表的第一个元素作为轴心值 m = nums[0] #创建一个新列表“l”,其中包含“

    34630

    77.如果用go语言,在 RANDOMIZED-QUICKSORT 的运行过程中,在最坏情况下,随机数生成器 RANDOM 被调

    二、如果用go语言,在 RANDOMIZED-QUICKSORT 的运行过程中,在最坏情况下,随机数生成器 RANDOM 被调用了多少次?在最好情况下呢?以θ符号的形式给出你的答案?...这是因为在最坏情况下,每次分区操作都会将数组分成大小相等的两部分,因此每次都需要从剩下的 n-1 个元素中随机选择一个元素作为主元。...这是因为在随机选择基准值时,有可能第一次选择的基准值就是排序数组中的最小值或最大值,这样就不需要再次调用 RANDOM 函数了。...如果第一次选择的基准值不是最小值或最大值,那么需要再次调用 RANDOM 函数来生成一个新的随机数。...由于我们将较小的一份作为基准值,所以我们需要对较大的一份进行递归调用。这个过程会一直持续到每个子数组的大小为1,此时我们就可以直接将它们按照随机数排序。因此,总共需要进行nlogn次递归调用。

    50470

    【算法】快速排序法(一)(二)(三)

    ,但是在多数的情况下,快速排序法的效率表现是相当不 错的。...快速排序法的基本精神是在数列中找出适当的轴心,然后将数列一分为二,分别对左边与右边 数列进行排序,而影响快速排序法效率的正是轴心的选择。...这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解, 也最符合轴心分割与左右进行排序的概念,适合对初学者进行讲解。...解法这边所介绍的快速演算如下:将最左边的数设定为轴,并记录其值为 s 廻圈处理: 令索引 i 从数列左方往右方找,直到找到大于 s 的数 令索引 j 从数列左右方往左方找,直到找到小于...,而之前曾经说过,快速排序法的 加速在于轴的选择,在这个例子中,只将轴设定为中间的元素,依这个元素作基准进行比较, 这可以增加快速排序法的效率。

    80550

    【优选算法篇】化繁为简,见素抱朴:从乱象中重构秩序的艺术

    分治专题(一):快速排序核心思想与应用 欢迎讨论:如果你有任何问题或见解,欢迎在评论区留言。 点赞、收藏与分享:如果觉得这篇文章对你有帮助,请点赞、收藏并分享给更多朋友。...通过分治的思想,递归对两侧的分区进行排序。 随机选择基准元素: 快速排序的效率受基准元素的选取影响。若基准选取不佳,递归的深度增加,影响排序性能。...使用随机基准元素有效避免最坏 O(n^2) 的情况,提升了排序效率。 空间复杂度:O(log n),主要为递归栈的空间消耗,最坏情况为 O(n)。...) 算法思路: 快速选择算法是快速排序的变种,可以在不完全排序的情况下找到第 k 大的元素,从而将时间复杂度控制在 O(n)。...通过分区,将数组划分为小于基准、等于基准和大于基准的三部分,逐步缩小查找范围,直到找到前 k 小的元素。 分区策略: 使用随机基准元素,将数组划分为小于基准、等于基准和大于基准的三部分。

    18410

    【算法入门】用Python手写五大经典排序算法,看完这篇终于懂了!

    选择输入列表的第一个或最后一个元素会不会一样? 由于快速排序算法的工作原理,递归级别的数量取决于pivot每个分区的结尾位置。在最佳情况下,算法始终选择中值元素作为pivot。...对于快速排序,那将是最坏的情况。 如你所见,快排的效率通常取决于pivot选择。如果输入数组未排序,则将第一个或最后一个元素用作,pivot将与随机元素相同。...但是,如果输入数组已排序或几乎已排序,则使用第一个或最后一个元素作为pivot可能导致最坏的情况。pivot随机选择使其更有可能使快排选择一个接近中位数的值并更快地完成。...从理论上讲,如果算法首先专注于找到中值,然后将其用作pivot元素,那么最坏情况下的复杂度将降至O(n log 2 n)。...你可以将其简化为O(n log 2 n),因为对数部分的增长快于线性部分。 随机选择pivot使最坏情况发生的可能性很小。这使得随机pivot选择对于该算法的大多数实现都足够好。

    1.9K10

    深入理解快速排序和STL的sort算法

    为了证明笔者没有放弃这块阵地,整合三篇去年的文章,今天一起来学习一下:快速排序及其优化 和 STL的sort算法 通过本文你将了解到以下内容: 快速排序的基本思想 快速排序的递归实现和迭代实现 快速排序的最坏情况...个人感觉 与其叫坑不如叫备份,但是如果你代码使用的是基于指针或者引用的swap,那么就没有坑的概念了。 这就是覆盖和交换的区别,本文的例子都是swap实现的,因此没有坑位被最后覆盖一次的过程。...可以明显看出来,快速排序在选择基准值时对整个分治过程影响很大,因为下一个环节的分治是基于前一环节的分割结果进行的。...4.2 分区不均匀和最坏复杂度 4.2.1 极端分区 考虑一种极端的情况下,如果基准值选取的不合理,比如是最大的或者最小的,那么将导致只有一边有数据,对于已经排序或者近乎有序的数据集合来说就可能出现这种极端情况...抛开语境一味地对比孰好孰坏其实都没有意义,内省式排序就是集大成者,为了能让排序算法达到一个综合的优异性能,内省式排序算法结合了快速排序、堆排序、插入排序,并根据当前数据集的特点来选择使用哪种排序算法,让每种算法都展示自己的长处

    1.6K30

    快速排序(Java分治法)

    ,也就是本次划分的区间; 右侧扫描过程:将基准记录与j指向的记录进行比较,如果j指向记录的关键码大,则j前移一个记录位置。...重复右侧扫描过程,直到右侧的记录小(即反序),若i<j,则将基准记录与j指向的记录进行交换; 左侧扫描过程:将基准记录与i指向的记录进行比较,如果i指向记录的关键码小,则i后移一个记录位置。...快速排序的过程上,每次分区都要遍历待分区区间的所有数据,所以,每一层分区操作所遍历的数据的个数之和就是n。...3.4 性能影响因素 快速排序算法的性能取决于划分的对称性。通过修改算法partition,可以设计出采用随机选择策略的快速排序算法。...在快速排序算法的每一步中,当数组还没有被划分时,可以在a[p:r]中随机选出一个元素作为划分基准,这样可以使划分基准的选择是随机的,从而可以期望划分是较对称的。

    1.1K10

    快速排序解读(基于java实现)

    它的基本思想是选择一个基准元素,通过一趟排序将待排序的元素分割成独立的两部分,其中一部分的所有元素都小于基准,另一部分的所有元素都大于基准,然后对这两部分继续进行排序,直到整个序列有序。...左指针从左往右移动,直到找到一个大于基准的元素;右指针从右往左移动,直到找到一个小于基准的元素。若找到,则交换这两个元素。重复步骤3,直到左指针和右指针相遇。相遇位置即为基准元素的最终位置。...以基准元素的最终位置将序列分成两部分,对这两部分分别进行快速排序(递归调用上述步骤)。递归结束时,序列变为有序。快速排序的关键在于基准元素的选择和分区操作。...合理选择基准元素可以提高排序效率,一般采用随机选择的方式。分区操作将序列划分为两部分,可以通过双指针的方式实现。...快速排序的时间复杂度取决于基准元素的选择和序列的划分情况。

    37721

    数据结构与算法-随机快速排序

    在实际应用中,快速排序的性能通常优于其他O(n log n)排序算法,但如果基准选择不当,可能会导致最坏情况的时间复杂度退化为O(n^2)。...为了避免这种情况,可以使用随机化快速排序,即随机选择基准元素,这样可以显著减少最坏情况发生的概率。...递归排序:递归地对左右两个部分进行排序。 二、随机化快速排序的步骤 假设有一个数组 arr 需要进行排序。 选择基准:随机选择数组中的一个元素作为基准。...最坏情况:如果每次都选择到最差的基准(即最小或最大的元素),时间复杂度为O(n^2)。但通过随机选择基准,这种情况的概率大大降低。 平均情况:随机化快速排序的平均时间复杂度为O(n log n)。...在需要对大量数据进行排序时,随机化快速排序是一个非常好的选择。

    17310

    大佬的快速排序算法,果然不一样

    算法的基本思想很简单,然而想要写出一个高效的快速排序算法并不是那么简单。基准的选择,元素的分割等都至关重要,如果你不清楚如何优化快速排序算法,本文你不该错过。...我们来看一下有哪些可选择策略。 选择第一个或者最后一个 如果待排序数是随机的,那么选择第一个或者最后一个作基准是没有什么问题的,这也是我们最常见到的选择方案。...而它的时间复杂度就是最差的情况O(N^2)。因此这种策略是绝对不推荐的。 随机选择 随机选择基准是一种比较安全的做法。因为它不会总是产生劣质的分割。...例如对于前面提到的数组,首先对区间[0,8]进行分区操作,之后得到两个新的分区,1,2,3和9,7,6,10,8,假设两个区间仍然可以使用快速排序,那么需要将区间[0,2]和[5,8]的其中一个压栈,另一个继续分区操作...我们需要在数据量小于一定值的时候,就不再继续进行分区操作了,而是选择插入排序(为什么?)。 那么问题来了,如何选择栈的大小呢?

    70120

    不同场景下 快速排序的几种优化方式你懂不?

    如果面试中遇到快速排序的问题,那就要小心了,面试官出快排的题目基本上都是鸡贼地给你挖好坑等着你,所以我们要做到逢山开路遇水搭桥,要不然等着我们的大概就只有这个场景了: ?...通过本文你将了解到以下内容: 快速排序和归并排序的分治过程对比 快速排序分区不均匀的影响 快速排序的随机化基准值 快速排序的三分区模式 快速排序和插入排序的混合 快速排序的分区过程 快速排序和归并排序采用的基本思想都是分治思想...可以明显看出来,快速排序在选择基准值时对整个分治过程影响很大,因为下一个环节的分治是基于前一环节的分割结果进行的。...快速排序划分不均匀情况 考虑一种极端的情况下,如果基准值选取的不合理,比如是最大的或者最小的,那么将导致只有一边有数据,对于已经排序或者近乎有序的数据集合来说就可能出现这种极端情况,还是来画个图看下:...最坏复杂度相当于每次从n-i个元素中只找到1个数据,将所有情况累加也就达到了O(n^2)级别,并不是递归过程全都挑选了最值作为基准值才会出现O(n^2)的复杂度,复杂度是一个概率化的期望值,具体的系数不同影响也很大

    87420

    【数据结构与算法】:选择排序与快速排序

    ,再进行交换,这就是选择排序的完整过程 1.1复杂度分析 时间复杂度 最好、平均、最坏情况下的时间复杂度都是 O(n^2) 原因在于,不管数组的初始顺序如何,选择排序都需要比较所有未排序的元素来找到最小...为了简单起见,我们选择数组的第一个元素作为枢轴。实际应用中可能会使用更复杂的选择方法,如随机选择或三数中值法,以避免最坏情况的性能下降。...最好情况、平均情况和最坏情况: 最好情况:当每次分区操作都能将数组均等分成两部分,快速排序的性能接近其理论最优。...平均情况:在随机选择的数组中,快速排序的平均时间复杂度也是( O(n \log n) )。...这是因为每一层递归调用都需要一定的空间,而递归树的深度直接影响调用栈的大小 2.5 代码优化:三数取中法选key 三数取中法是在实现快速排序时用来提高性能并降低遇到最坏情况概率的一种技术。

    65110

    快速排序(基础版)

    快速排序是一种采用分治思想,在实践中通常运行较快一种排序算法,它的思路如下 对于一个无序数组(排序前先将数组随机打乱) ? 首先,任意选取一个元素(这里选择数组第一个元素),该元素称为中轴元素 ?...然后对左右两个子数组分别按照同样的方法进行分割操作(递归进行) 一直递归分割到子数组只有一个或零个元素为止,此时整个数组有序 ? 子数组是相对而言的 那这个分割操作是怎么进行的呢? ? ? 一尘 ?...对于规模为N的数组 如果数组有序的话,此时是最坏情况,因为每次递归右子数组规模只比原数组减一,这样递归次数就会很多 每次分割后,数组都会被划分一个大小为0的子数组和原数组大小减一的子数组 ?...排序前先将数组随机打乱就是防止输入为有序数组而导致排序效率低下,随机打乱将这种可能性(有序)降为极低 ? 最好情况 ?...最好情况就是每次选到一个中轴元素刚好位于中间,此时两个子数组刚好是原数组的一半,那么 T(N)= 2*T(N/2)+O(N) ? ? ? logN个等式推导请看:归并排序 ? 平均情况 ?

    90130

    Lucene系列(14)工具类之快速选择算法

    快速选择及其变种是实际应用中最常使用的高效选择算法。 快速选择的总体思路与快速排序一致,选择一个元素作为基准来对元素进行分区,将小于和大于基准的元素分在基准左边和右边的两个区域。...对于快速排序,想必大家对其原理都很清楚,这里不赘述了。 众所周知,快速排序最坏的时间复杂度是 O(n2). 快速选择也是。 最坏情况通常出现在每次选择分割点时,都选择了最错误的那个。...我猜想的算法思路:之所以随机选择法,会出现最坏的情况,是因为每次都选择到了最差也就是最大的数字。加入三个数字的中位数,可以保证选择到的分割点既不是最大,也不是最小,刻意避免了最坏的情况出现....所以实际应用中的最佳快速选择实现,应该是使用三者中位数法选取分割点,设置阈值,如果遇到了极端情况,切换到中位数的中位数 (BFPTR) 来保证最坏情况下的时间复杂度 真巧呢,Lucene 就是这么实现的...代码如下: image.png 其中涉及到一个对 5 个以内的元素求中位数并且分区的方法,其实本质上就是直接进行了插入排序,然后取中位数。

    80210

    快速排序你真的会了吗?

    正如它的名字所体现,快速排序是在实践中最快的已知排序算法,平均运行时间为O(NlogN),最坏的运行时间为O(N^2)。算法的基本思想很简单,然而想要写出一个高效的快速排序算法并不是那么简单。...基准的选择,元素的分割等都至关重要,如果你不清楚如何优化快速排序算法,本文你不该错过。 算法思想 快速排序利用了分治的策略。...我们来看一下有哪些可选择策略。 选择第一个或者最后一个 如果待排序数是随机的,那么选择第一个或者最后一个作基准是没有什么问题的,这也是我们最常见到的选择方案。...而它的时间复杂度就是最差的情况O(N^2)。因此这种策略是绝对不推荐的。 随机选择 随机选择基准是一种比较安全的做法。因为它不会总是产生劣质的分割。...例如对于前面提到的数组,首先对区间[0,8]进行分区操作,之后得到两个新的分区,1,2,3和9,7,6,10,8,假设两个区间仍然可以使用快速排序,那么需要将区间[0,2]和[5,8]的其中一个压栈,另一个继续分区操作

    70620
    领券