第一章:各种款式的算法复杂度例子+计算小技巧

一:算法概念介绍:

“算法是对特定问题求解步骤的一种描述;

一个算法需要具备五个重要的基本特征:

(1)有穷性。即一个算法必须是在有穷步后结束的,每一步都是在有穷的时间内完成的。(也就是算法不能是无穷无尽执行的死循环)
(2)确定性。算法的每一条指令都必须有确切的含义,相同的输入只能得到相同的输出。
(3)可行性。算法中描述的操作,都可以通过已经实现的基本运算执行有限次实现。也就是不包含不能实现的运算逻辑。
(4)一个或者多个输入。
(5)一个或者多个输出。

一个“好”算法需要具备四个重要的基本特征:

(1)正确性。能正确解决问题。(正确)
(2)可读性。易读,便于人们理解。(简单易读)
(3)健壮性。有些也称之为鲁棒性(robust),是指软件对于规范要求以外的输入情况(非法数据等)的处理能力。(容错)
(4)高效率/低存储。所谓高效率就是稍后主要演示的时间复杂度。低存储就是指算法执行过程中需要的最大存储空间。(运行时间快,占用空间小)

二:算法时间复杂度

算法复杂度一定一定是指这段算法在“最坏”的情况下的复杂度。什么平均啊,什么最优啊,一般都不考虑!
一个算法时间复杂度,很大程度上决定着算法的优劣,实现同一个功能,A程序一分钟执行完,B程序跑了一小时,结果不言而喻。怎么从代码层面,分析代码的时间复杂度,就是接下来大量例子解释的内容。
首先,算法复杂度采用“大O表示法”,例如:O(n)
这里的O,意思是 “On the order of ( n ) " 表示着当数据规模是n时,这套算法运行的时间为数据规模的多少“阶”,这也是为什么我们仅需要保留“最高阶”作为算法的时间复杂度的原因。

关于阶数大小的比较一定要记住,才能记得保留哪个:

在这里插入图片描述

三:通过例子和小技巧彻底搞懂如何得出复杂度

这里将总结了几种常见的算法逻辑类型,可以由简单到难通过各种方式去求得时间复杂度

时间复杂度

一:加法规律
在这里插入图片描述
这是最简单的一种情况,n,m 是传进来的参数,也就是代表着需要处理的数据规模,分别两个循环对其进行处理,复杂度就是简单的取nm两者较大那个O( max(m,n) ) 即可。例如m=6,n=3 ;O( max(m,n) ) = O(m)

二:乘法规律
在这里插入图片描述
这一种相比上面那种难看一点,因为有一个for嵌套进去了,但是也很简单,既然nm互不干扰,也就是外层每执行一次,内层都执行m次,那么总的执行次数就是:O(n*m)
但是这里有个坑点,嵌套循环中,内层循环不受外层循环限制才能使用乘法原则⚠️

三:带条件判断类型
这一种类型是各种面试考试最最常见的一种,因为它判断的参数可以写得非常恶心难看,但是用下面的方法去解决,都很简单。
假设执行次数法
循环+参数条件判断类型
(1)假设执行总次数为t
(2)罗列出每一步i的变化情况,直到假设执行到t次(或者其它参数的变化规律)
(3)找到判断条件,把t解出来,就是所求的时间复杂度
记住这三步,结合例题看:

1:在这里插入图片描述

在这里插入图片描述

(2)在这里插入图片描述

在这里插入图片描述

(3)在这里插入图片描述

在这里插入图片描述

(4)

在这里插入图片描述
在这里插入图片描述

(5)在这里插入图片描述

在这里插入图片描述

综上,可以看到总结出来的基本套路就是那几步就可以轻松解决这一类问题,而且每一小步都很清晰很简单。不断假设t为1,2,3… 随着执行次数的增加,条件参数一定会发生变化,然后假设执行到t次,这个时候把关于条件参数关于t的数学归纳式跟判断条件联合起来,求出t,就是所求的时间复杂度。

四:多层循环嵌套类型,公式法
这里的多层循环嵌套和例子二的简单循环嵌套不一样,这种题型一般是最恶心的,它内层执行次数并不独立,而是受外层循环的变量的制约。但是这种也有固定的求解步骤和思路,一样可以做得很简单。但是我们需要借助一些累加求和公式:

公式解释
在这里插入图片描述

二重循环
在这里插入图片描述
在这里插入图片描述

三重循环
在这里插入图片描述
这种长得很丑,但是一定切记不能用乘法原则简单相乘!道理很简单,每一层的内层,都受外一层制约
这种代入公式,得:
在这里插入图片描述

之前好像也听过一种说法,说是以同一个数据规模n为基础,套k层的循环,不管i,j,k 怎么约束,无脑写 O(n^k) 也是可以的,但是我不知道对不对,也不知道怎么去证明,希望有懂的大佬可以解释一下

五:递归类型
递归类型遇到的比较少,但是也比较好处理,它递归处理逻辑一定会修改变量,也就是每一层都会对变量进行一定固定的操作,例如第一层-1,第二层-1,第三次-1,直到x<0;这个递归的复杂度就是n,例如:
在这里插入图片描述
结果就是O(n)
死盯着数据规模n从n到1即可,不要被它什么return n*XX吓到,我只关心它执行了多少次!它开心写多几个hello world都不会影响时间复杂度。

以上就是我的个人小技巧总结和分享,很多问题摘抄自王道版的数据结构习题,希望大佬们可以一起讨论学习~

猜你喜欢

转载自blog.csdn.net/whiteBearClimb/article/details/127736855