递归总共执行了这个语句多少次
递归执行顺序画成树形结构,我们称之为递归树
求Fibonacci数列的第n项
Fib: 0, 1, 1, 2, 3, 5, 8, 13 …
F(n) = F(n - 1) + F(n - 2);
// 面试,直接用递归
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
这段语句的时间复杂度分析
/*
要计算fib(6)因为6不小于2,所以就要计算fib(5) + fib(4),所以就变成要计算fib(6)至少要计算一个fib(5),也要计算一个fib(4),所以至少多出了2个运算,同理可得,计算fib(5)和fib(4)就要计算fib(2)和fib(3)....
从上图中我们可以看到两个现象
第一个现象就是它每多展示一层的话,运行的节点数就是上面一层的两倍,所以每一层它的节点数也就是它的执行次数,是按指数级递增的,由此可见下到第n层对的话,就变成执行2^n,当前是6,所以总共执行2^6,所以总的执行次数变成了指数级
第二个现象就是重复节点有很多,就是因为这么多重复的节点导致求第6个fib的执行次数为2^6
所以如果有缓存的话,一个节点只计算一次,那么就是O(n);
*/
主定律是计算所有递归的函数如何计算它的时间复杂度
第一种: 二分查找O(logn): 一分为二只查一边时间复杂度为O(logn)
第二种: 二叉树遍历O(n): 每次一分为二,但每次一分为二之后,每一边是相等的时间复杂度T(n) = 2T(n/2) + O(1),另一个维度思考每个节点只访问一次,所以是O(n)
第三种: 二维有序矩阵查找 O(n) (一维有序数组二分查找 O(logN))
第四种: 归并 O(nlogn)
二叉树:
前,中,后序 遍历O(n), n为节点总数,每个节点访问一次且仅访问一次,所以时间复杂度线性于节点总数