快速搞定算法的复杂度

时间:2024-05-23 17:09:15

首先,有些人可能会问:平时我在写程序的时候根本就不关心这个,为什么要注意算法的复杂度呀?首先的话,我想告诉你,如果你不关心算法的复杂度的话,这是一件非常危险的事情,至少说它是一件相对来说比较业余的事情。为什么这么说呢?这就比如你在沙哈拉沙漠里迷路了,你就必须知道你的水壶里还有多少水(当然如果你没带水壶的话,这就不好说了,哈哈)。
快速搞定算法的复杂度
首先,算法的复杂度包括时间复杂度和空间复杂度。要检验一个算法最简单的方法就是让程序运行一遍,它所消耗的时间自然也就知道了,但是不妙的是,由于不同的电脑有不同的运行环境,自然同一个程序在不同的电脑上运行的时间就会有差别,当两台电脑的运行环境差别太大时,这种方法所得结果就不可信了。况且我们在写算法的时候,根本就没办法把完整的代码运行。所以呢,我们就引入了时间复杂度。由于这种方法用大O来表示,因此,我们通常称之为【大O号表示法】,这时,时间复杂度T(n)=O(f(n)).常见的时间复杂度根据不同的级别可以分为以下几种:

常数阶O(1),如下图所示:
由名称可知,算法的时间不会因为变量的增加而增加,这样的代码再长,也可以用O(1)来表示,当然O(2),O(3)……都相当于O(1)。
快速搞定算法的复杂度
2.线性阶O(n),如下图所示:
快速搞定算法的复杂度
这段代码中的i放在了一个循环里面,一共循环了n次,也就是说这段代码一共执行了n次,因此它的时间复杂度为O(n)。

3.平方阶O(n^2),如下图所示:
快速搞定算法的复杂度
由于这段代码是一个双重循环,一共执行了n*n次,而且随着n的增大,CPU的工作量或者说要运行它花费的时间成平方的增长,因此我们把它的时间复杂度称为O(n^2)。

4.立方阶O(n^3),有以下两种:

1)如下图所示、
快速搞定算法的复杂度
一个三重循环,其中的每一个循环的结束条件都是小于同一个数n,很显然count++一共做了n^3 次。我们就称它的时间复杂度为O(n^3)。

2)第二种立方阶叫做变形立方阶,如下图所示:
快速搞定算法的复杂度

它与第一种立方阶的区别是内层循环的控制条件不同,count++的执行次数变为了n*(n+1)((2n+1)/6,下面我们来分析一下:快速搞定算法的复杂度
分析可知1一共循环了n次,2一共循环(n-1)次,3一共循环(n-2)次……以后循环的次数逐步递减。那么第n棵树上的叶子数为1+2+3+……+n = (n+1)/2。因此整棵树上的叶子数为(2
1 + 32 + 43 + 54+……(n+1)n) /2 = n(n+1)(2n+1)/6。

  1. 对数阶O(logN),如下图所示:
    快速搞定算法的复杂度

这其实也是一个双重循环,但与上面的O(n)相比,内循环结束的条件不同,当i个2相乘的结果第一次大于n时,便会跳出循环。计2^i = n;得到i = log2(n),我们就称它的时间复杂度为O(logn)。

6.线性对数阶O(nlogN),如下图所示:
快速搞定算法的复杂度
这个很好理解,我们已经知道了对数阶的时间复杂度,由于线性对数阶O括号内的值为对数阶的n倍,因此我们只需将时间复杂度为对数阶O(logN)的代码再循环n遍就行了,这时改代码的时间复杂度为n*O(logN) = O(nlogN)。

空间复杂度是指执行这个代码所需的内存空间

下面介绍算法两种的空间复杂度:

空间复杂度O(1)同算法的时间复杂度一样,算法的空间复杂度为O(1)表示一个算法执行所需的临时空间不会随着某一个变量大小的变化而变化,O(2),O(3),O(4),……都可以用O(1)来表示。下面的代码空间复杂度为O(1):
快速搞定算法的复杂度
2.空间复杂度O(n),大家先看看这个例子:
快速搞定算法的复杂度
这是一个递归算法,每次调用自身都要分配内存空间,因此方法fun(a,n,0)的空间复杂度为O(n)。

下面给大家提供几个计算算法空间复杂度的方法:

①忽略常数,用O(1)表示

②递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间。

③对于单线程来说,递归有运行时堆栈,求的是递归最深的那一次压栈所耗费的空间的个数,因为递归最深的那一次所耗费的空间足以容纳它所有递归过程。

欢迎大家在评论区留言评论,谢谢!

另外,如果你觉得文章对你有用,在本文的开头点个关注吧!

最后

欢迎大家在评论区留言和评论,谢谢!

原创不易,莫要白票,请为本文点赞并在本文左上方点个 关注吧!这将是我写作更多优质文章的最强动力。
添加我的微信公众号,更多福利等你白票!
快速搞定算法的复杂度