递归算法的时间复杂度分析
递归算法的时间复杂度分析是比较麻烦的,涉及到了递归层数以及每层递归的时间复杂度。
逐层分解的情况
迭代法适用于问题的分解是一层一层,也就是说满足F(n) = aF(n - 1) + f(b)的情况,即数据规模为n的问题,可以分解为数据规模为n-1的情况的线性叠加。
汉诺塔为例
void hano(char A, char B, char C, int n) {
if (n > 0) {
hano(A, C, B, n - 1);
move(A, C);
hano(B, A, C, n - 1);
}
}
hano函数的时间复杂度为T(n) = 2 * T(n - 1) + O(1);有了这个递推公式,加上T(0) = 1,就可以推导出T(n)与n的关系为T(n) = 2 ^ n
倍数分解的情况(通常以二分更多)
这种情况下,通常时间复杂度满足T(n) = a×T(n/b) + f(n),其中f(n)是递归外的额外处理时间。
例如归并排序中,当划分完两边的数组后,需要合并数组的操作,这些额外的处理,时间复杂度就是f(n);
时间复杂度求解
当a和b确定时,光看递归的部分,它的时间复杂度就是:O(n^logba)。
由于时间复杂度求的是上界(upper bound),通过对比递归部分的时间复杂度和 f(n) 的大小关系,得出最后的整体时间复杂度。牢记以下三种情况和相应公式:
-
当递归部分的执行时间 nlog(b)a 大于 f(n) 的时候,最终的时间复杂度就是 O(n^logba)。
-
当递归部分的执行时间 nlog(b)a 小于 f(n) 的时候,最终的时间复杂度就是 f(n)。
-
当递归部分的执行时间 nlog(b)a 等于 f(n) 的时候,最终的时间复杂度就是 O(n^logba)logn。
归并排序为例
根据归并排序的递归调用方式可以得到时间复杂度满足T(n) = 2T(n/2) + n,此时b = 2时退化为二分递归,根据上述求解方式得到时间复杂度为O(nlogn)