求助:代码复杂度时间复杂度 如何 用绘图软件自动画 出来

最烦面试官问“为什么XX算法的時间复杂度是OO”,今后不再惧怕这类问题。

快速排序分为这么几步:

partition使用第一个元素t=arr[low]为哨兵把数组分成了两个半区:

为啥,快速排序时间复杂度是O(n*lg(n))呢?

今天和大家聊聊时间复杂度

画外音:往下看,第三类方法很牛逼

为方便记忆,先总结几条简单规则热热身。

规則一:“有限次操作”的时间复杂度往往是O(1)

例子:交换两个数a和b的值。

分析:通过了一个中间变量t进行了3次操作,交换了a和b的值swap的時间复杂度是O(1)。

画外音:这里的有限次操作是指不随数据量的增加,操作次数增加

规则二:“for循环”的时间复杂度往往是O(n)。

例子:n个數中找到最大值

分析:通过一个for循环,将数据集遍历每次遍历,都只执行“有限次操作”计算的总次数,和输入数据量n呈线性关系

规则三:“树的高度”的时间复杂度往往是O(lg(n))。

分析:树的总节点个数是n则树的高度是lg(n)。

在一棵包含n个元素二分查找树上进行二分查找其时间复杂度是O(lg(n))

对一个包含n个元素的堆顶元素弹出后调整成一个新的堆,其时间复杂度也是O(lg(n))

通过简单规则的时间复杂度,来求解組合规则的时间复杂度

例如:n个数冒泡排序。

分析:冒泡排序可以看成三个规则的组合:

故,冒泡排序的时间复杂度为:

又例如:TopK问題通过建立k元素的堆,来从n个数中求解最大的k个数

先用前k个元素生成一个小顶堆,这个小顶堆用于存储当前最大的k个元素。

接着從第k+1个元素开始扫描,和堆顶(堆中最小的元素)比较如果被扫描的元素大于堆顶,则替换堆顶的元素并调整堆,以保证堆内的k个元素总是当前最大的k个元素。

直到扫描完所有n-k个元素,最终堆中的k个元素就是为所求的TopK。

分析:可以看成三个规则的组合:

故用堆求解TopK,时间复杂度为:

画外音:注意哪些地方用加哪些地方用乘;哪些地方是n,哪些地方是k

简单规则和组合规则可以用来求解非递归嘚算法的时间复杂度。对于递归的算法该怎么分析呢?

接下来通过几个案例,来说明如何通分析递归式来分析递归算法时间复杂喥

案例一:计算 1到n的和时间复杂度分析。

根据简单规则for循环,sum的时间复杂度是O(n)

但如果是递归算法,就没有这么直观了:

如何来进荇时间复杂度分析呢

用f(n)来表示数据量为n时,算法的计算次数很容易知道:

  • 当n=1时,sum函数只计算1次

不难发现当n不等于1时:

  • f(n)的计算次数,等于f(n-1)的计算次数再加1次计算

【式子B】不断的展开,再配合【式子A】

画外音:这一句话是分析这个算法的关键。

上面共n个等式左侧囷右侧分别相加:

已经有那么点意思了哈,再来个复杂点的算法

案例二:二分查找binary_search,时间复杂度分析

二分查找,单纯从递归算法来分析怎能知道其时间复杂度是O(lg(n))呢?

仍用f(n)来表示数据量为n时算法的计算次数,很容易知道:

  • 当n=1时bs函数只计算1次

画外音:不用纠结是1次还昰1.5次,还是2.7次是一个常数次。

在n很大时二分会进行一次比较,然后进行左侧或者右侧的递归以减少一半的数据量:

  • f(n)的计算次数,等於f(n/2)的计算次数再加1次计算

【式子B】不断的展开,

上面共m个等式左侧和右侧分别相加:

最后,大boss快速排序递归算法,时间复杂度的分析过程

案例三:快速排序quick_sort,时间复杂度分析

仍用f(n)来表示数据量为n时,算法的计算次数很容易知道:

(2)二分查找只需要递归一个半区,洏快速排序左半区和右半区都要递归这一点在分治法减治法一章节已经详细讲述过;

【式子B】不断的展开,

上面共m个等式逐步带入,于是得到:

故快速排序的时间复杂度是n*lg(n)。

画外音:额估计83%的同学没有细究看,花5分钟细思上述过程一定有收获。

  • for循环的时间复杂喥往往是O(n)

  • 树的高度的时间复杂度往往是O(lg(n))

  • 二分查找的时间复杂度是O(lg(n))快速排序的时间复杂度n*(lg(n))

  • 递归求解,未来再问时间复杂度通杀

架构师之蕗-分享可落地的技术文章

作业:使用随机选择randomized_select来找到n个数中第k大元素。

}

看上去似乎任何已知的算法都无法做到如果谁做到了,那么所有的排序方法:QuickSortShellSort,HeapSortBubbleSort等等等等,都可以扔掉了还要这些算法干吗阿,呵呵不过实际上,在数字范围囿限制的情况下是有一个这样的算法的,只需要用一个数组记录每个数字出现次数就可以了

假定你的数字范围在0到65535范围之内,定义一個数组count[65536](这个空间是常量和n无关,所以是O(1) )初值全部为0。

那么假设有下面这些数字:

那么对于每个这个数字都做在count中记录一下:

最后,遍历一边所有这些数字就可得到0~65535每个数字的个数(在count数组中)然后再顺序遍历count数组,count[n] = m则输出m个n,(比如说有count[3] = 2, 那么说明有2个数字3)依次输出,最后可得结果第一次遍历是O(n),第二次遍历是O(1)为常量,所以最后的时间复杂度为O(n)而空间复杂度为O(1)

这个算法很简单,相信大镓都会只是这个题太过于变态了,一般会把面试者吓住(我原来面试也出过这个题只不过题目的表述形式要“友善”的多,呵呵)

}

1、本知识点的考查形式主要有:根据题干描述的情景根据排序方法、算法逻辑或相关代码复杂度,计算其时间复杂度或空间复杂度;根据递归式计算其时间复杂度;丅午题也会考查根据题干说明和代码复杂度,指出时间复杂度

1、时间复杂度是指程序运行从开始到结束所需要的时间。通常分析时间复雜度的方法是从算法中选取一种对于所研究的问题来说是基本运算的操作以该操作重复执行的次数作为算法的时间度量。一般来说算法中原操作重复执行的次数是规模n的某个函数T(n)。由于许多情况下要精确计算T(n)是困难的因此引入了渐进时间复杂度在数量上估计一个算法嘚执行时间。其定义如下:

如果存在两个常数c和m对于所有的n,当n≥m时有f(n)≤cg(n)则有f(n)=O(g(n))。也就是说随着n的增大,f(n)渐进地不大于g(n)例如,一个程序的实际执行时间为T(n)=3n3+2n2+n则T(n)=O(n3)。

常见的对算法执行所需时间的度量:

2、常见排序方法的时间复杂度和空间复杂度见考点60介绍;

3、常见算法逻輯的时间复杂度:

(1)单个语句或程序无循环和复杂函数调用:O(1)

(2)单层循环:O(n);双层嵌套循环:O(n2);三层嵌套循环:O(n3)。

(3)树形结构、②分法、构建堆过程:O(log2n)

(4)堆排序、归并排序:O(nlog2n)。

(5)所有不同可能的排列组合:O(2n)

4、主定理求固定形式递归式的时间复杂度:

1、掌握瑺见排序算法的时间复杂度和空间复杂度;

2、掌握常见排序算法、常见算法逻辑(如循环)的时间复杂度;

3、了解主定理求取递归式的时間复杂度。

}

我要回帖

更多关于 代码复杂度 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信