代码随想录学习之---递归算法复杂度分析

递归算法复杂度分析

问题:求x的n次方
O(n)的解法:

int function1(int x, int n) {
	int t = 1; //x的0次方是1
	for (int i=0; i < n; i++)
		t = t * x;
	return t;
}

上面方法的思路很简单,就是每次多乘一个x,一共n个x相乘所以一个for循环搞定,时间复杂度也不难看出来是O(n)。但是,有没有其他的办法呢?

递归算法

递归算法可以分为三个步骤:①定义函数②找到等价关系式③确定终止条件
----以斐波那契数列为例—
定义函数:fib(n)
找到等价关系式:fib(n-1)+fib(n-2)
终止条件:if (n <= 2) fib(n) = 1

那么最开始的问题也可以想办法用递归的办法想,n个x相乘等价于 (n-1)个x * x 。如此,递归下去当n=0时就是终止条件了嘛,此时结果为0

int function2(int x, int n) {
	if (n == 0)
		return 1;
	return function2(x, n-1) * x;
}

首先,需要明确递归算法的时间复杂度是 递归的次数 × 每次递归中的操作数
每次递归中仅有一个相乘的操作,其实他的时间复杂度也是O(n)。举个例子,当n=3时,第一次递归后:n=2;第二次递归后,n=1;第三次递归后,n=0此时返回1.

那么有没有更好的办法呢?分析一下可以发现,n要么是奇数,要么是偶数。如果n是偶数,那么此时可以看成x的n/2次方 × x的n/2次方。如果n是奇数,可以看成是x × x的偶数次方(回到了第一种情况)。

int function3(int x, int n) {
	if (n == 0)
		return 1;
	if (n % 2 == 1)
		return funtion3(x, n / 2) * funtion3(x, n / 2) * x;
	return funtion3(x, n / 2) * function3(x, n/2);
}

那么时间复杂度怎么分析呢?假设n=16,
第一次递归,可以分为2个节点,每个节点有8个x相乘
第二次递归,可以分为4个节点,每个节点有4个x相乘
第三次递归,可以分为8个节点,每个节点有2个x相乘
看成一个满二叉树的话,一共有15个节点,每个节点有一次相乘操作。所以时间复杂度O(n-1),也就是O(n)。
进一步可以对上面的函数进行优化,function3(x, n/2)被计算了两次,其实计算一次就可以了没必要浪费时间。

int funciton4(int x, int n) {
	if (n == 0)
		return 1;
	int t = funtion4(x, n/2);
	if (n % 2 == 1)
		return t * t * x;
	return t *t;
}

这里仅仅有一个递归调用,且每次都是n/2 ,所以这里我们一共调用了log以2为底n的对数次。如果n是奇数,那就有2次相乘,n是偶数那就有1次相乘,最后时间复杂度是O(logn)。

此文章为本人学习笔记,水平有限请多包涵。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值