一. 时间复杂度
1. 含义
递归算法的时间复杂度为:
递归次数
∗
每次的递归时间
递归次数*每次的递归时间
递归次数∗每次的递归时间
一般每次的递归时间为O(1),实际时间复杂度就是递归次数,递归次数的求解就要列出树来算节点数了,通常用到求满二叉树节点数的公式:
2
k
−
1
,其中
k
表示树的深度
2^k-1,其中k表示树的深度
2k−1,其中k表示树的深度
假如递归函数为如下类型,给出了n = 1、n = 0的递归结束出口,因此画出树到f(0)、f(1)即可,如下为当n = 5时的树:
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n - 1) + f(n - 2);
}
因此,可以知道为n时,树的节点数就是满二叉树的节点数,可以看出树的深度也为k = n,因此树的节点数就是
2
n
−
1
2^n-1
2n−1
又因递归次数等于节点数,所以该递归函数的时间复杂度为为
O
(
2
n
)
O(2^n)
O(2n)
2. 模型
根据递归函数最后的return f(),可以总结出如下几种递归函数的时间复杂度:
- 模型1:时间复杂度为 O ( 2 n ) O(2^n) O(2n)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n - 1) + f(n - 2); //根据这个快速判断时间复杂度
}
- 模型2:时间复杂度为 O ( n ) O(n) O(n)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n - 1); //根据这个快速判断时间复杂度
}
- 模型3:时间复杂度为 O ( l o g n ) O(logn) O(logn)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n/2); //根据这个快速判断时间复杂度
}
- 模型4:时间复杂度为 O ( n ) O(n) O(n)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n / 2) + f(n / 2); //根据这个快速判断时间复杂度
}
二. 空间复杂度
1. 含义
空间复杂度实际就是求解数的深度k,然后乘以每次递归函数的空间复杂度,一般没有创建数组的递归函数空间复杂度为O(1),所以实际就是求树的深度,最终得到空间复杂度为
O
(
k
)
O(k)
O(k)
假如递归函数为如下类型,给出了n = 1、n = 0的递归结束出口,因此画出树到f(0)、f(1)即可,如下为当n = 8时的树:
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n / 2);
}
可以看出树的深度为4,推论到n = n时,可以知道树的深度为logn + 1,所以该递归函数的空间复杂度为:
O
(
l
o
g
n
)
O(logn)
O(logn)
2. 模型
总结出如下几种模型的空间复杂度:
- 模型1:空间复杂度为 O ( n ) O(n) O(n)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n - 1) + f(n - 2); //根据这个快速判断时间复杂度
}
- 模型2:空间复杂度为 O ( n ) O(n) O(n)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n - 1); //根据这个快速判断时间复杂度
}
- 模型3:空间复杂度为 O ( l o g n ) O(logn) O(logn)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n/2); //根据这个快速判断时间复杂度
}
- 模型4:空间复杂度为 O ( l o g n ) O(logn) O(logn)
int f(int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return f(n / 2) + f(n / 2); //根据这个快速判断时间复杂度
}