接下来看看算法
从时间复杂度开始
时间复杂度的计算
确定基本操作
首先,确定算法中的基本操作,即算法中重复执行次数最多的操作。这通常是赋值、比较、循环体内的操作等。
计算基本操作执行次数
然后,计算基本操作执行次数与输入规模(通常用n表示)之间的关系。这通常涉及到对算法中循环结构的分析。
- 对于循环,需要确定循环体执行的次数。这可能与输入规模n直接相关,也可能与循环内部的条件判断有关。
- 对于递归,需要找出递归的递推关系式,并确定递归的深度和每层递归中基本操作执行的次数。
忽略低阶项和常数项
在计算得到基本操作执行次数与n的关系后,通常可以忽略掉关于n的低阶项和常数项,因为它们对于算法执行时间随n增长的趋势影响较小。
使用大O表示法
最后,将计算得到的基本操作执行次数与n的关系,转换为大O表示法。大O表示法会给出算法执行时间随n增长的上界。
示例
假设有一个算法,它包含了一个循环,循环体内的基本操作执行了n次,然后是另一个循环,循环体内的基本操作执行了n^2次。该算法的时间复杂度可以这样计算:
- 总的基本操作次数为 n + n^2。
- 忽略低阶项n,得到 n^2。
- 使用大O表示法,表示为 O(n^2)。
常见的时间复杂度
- O(1):常数时间复杂度,算法执行时间不随输入规模n的增长而增长。
- O(log n):对数时间复杂度,常见于二分查找等算法。
- O(n):线性时间复杂度,算法执行时间与输入规模n成正比。
- O(n log n):常见于归并排序、快速排序等排序算法。
- O(n^2)、O(n^3)、...:多项式时间复杂度,算法执行时间随输入规模n的幂次方增长。
- O(2^n)、O(n!):指数时间复杂度和阶乘时间复杂度,这类算法通常不适合处理大规模数据。
接下来用汉诺塔问题开始举例子
设将n个圆盘从一根柱子移动到另一根柱子所需的最少移动次数为T(n)。
-
基本情况:当只有一个圆盘时(n=1),显然只需要移动一次,即T(1) = 1。
-
递归关系:对于n个圆盘,我们可以将其分解为三个步骤:
- 将n-1个圆盘从A移动到B(使用C作为辅助柱子),这一步需要T(n-1)次移动。
- 将剩下的最大圆盘(第n个)从A移动到C,这一步需要1次移动。
- 将n-1个圆盘从B移动到C(使用A作为辅助柱子),这一步又需要T(n-1)次移动。
因此,总的移动次数为 T(n) = 2*T(n-1) + 1。
-
求解递归关系:
这个递归关系实际上是一个等比数列的求和问题,其中公比为2,首项为1(当n=1时)。
通过数学归纳法或观察法,我们可以得到通项公式为:T(n) = 2^n - 1。 -
汉诺塔问题的时间复杂度是O(2^n),其中n是圆盘的个数。
正在研究其他算法ing,还没搞懂 一天搞一点点,进度有点稍快了