详解快排及其应用

912. 排序数组

215. 数组中的第K个最大元素

剑指 Offer 40. 最小的k个数

 

排序算法千千万,今天先讲快排!!

关于「详解归并排序及其应用」,可见 详解归并排序及其应用

算法思想

「快排」其实是先把一个元素的位置排好,然后递归该元素的两边即可

10

当我们把第一个元素的位置安顿好后,剩余的元素只需要递归处理即可,分别递归区间[lo, j - 1][j + 1, hi]

现在来分析一下「快排」的时间复杂度,先看图:

11

对于长度为n数组来说,树的每一层处理时间为n;如果树趋于一棵平衡二叉树,那么树高为logn

所以最终时间复杂度为o(nlogn)

但是,存在一种特殊情况,如果这颗树长歪了??如下图所示:

12

那么,此时的树高变为了n,时间复杂度退化为o(n^2)

出现这种情况的例子也很简单,如果原数组已经有序,那么就会出现这种情况,不信可以手动模拟一下!!

如何解决这种情况呢?

注意:快排是一种「不稳定」排序;归并是一种「稳定」排序!!

「不稳定」表示值相等的元素可能会被改变原来的顺序

算法框架

算法应用

最简单的应用肯定就是给一个数组,然后排序。如题目 排序数组

今天来介绍几个难「亿」点的题目

数组中的第K个最大元素

题目详情可见 数组中的第K个最大元素

当我们安顿的元素位置恰好为K时,那么该元素即为数组中的第 K 个最元素

看到很多人说面试会问这种写法的时间复杂度,先给出答案o(n)

基础的快排框架下,每一层需要处理的节点数都为n,而这个题目类似于二分,每次只需要处理一半的节点数量

假设在完美的情况下,partition()中返回的p都是中间值,这样就可以完美平分节点数量

所以第一次需要处理 n 个节点,第二次需要处理 n2 个节点,第三次需要处理 n4 个节点,以此类推...

综上,一共需要处理 n+n2+n4+=n+n(12+14+)

根据等比数列求和公式:12+14+=112n=1

所以一共需要处理 2n 次,故时间复杂度为o(n)

剑指 Offer 40. 最小的k个数

题目详情可见 剑指 Offer 40. 最小的k个数

和上一题大同小异,当我们安顿的元素位置恰好为K时,那么该元素及其左边的元素即为数组中最小的 k 个数