【算法】从x的n次方看递归时间复杂度计算
从x的n次方看递归时间复杂度计算
1.循环
这个问题,最简单的办法是用循环
1 | int pow1(int x,int n) |
如上算法的时间复杂度为O(N)
,但还是不够理想。这时尝试使用递归算法
2.递归1
1 | int pow2(int x,int n) |
使用如上递归函数时间复杂度计算办法,该函数递归调用次数是从n
一直减到0,即n次。每次递归中,需要进行一次相乘的计算,即O(1)
最终得到的时间复杂度 O(n*1) = O(n)
,这和我们用循环写出来的代码没两样
3.递归2,二叉树
1 | int pow3(int x,int n) |
最终求次方操作被抽象成了一个二叉树
总递归次数,即二叉树中的节点个数。我们能算出来这颗满二叉树的节点个数为 2^4-1 = 15
所以一共递归了15次,每次的操作还是一个相乘,O(1)
所以最终的时间复杂度就是
1 | 递归次数 = 满二叉树节点个数 = 2^m -1 |
带入可以计算出来,最终的二叉树总节点数是n-1
个,时间复杂度还是O(N)
。这说明我们的算法还不够好
4.递归3
如果观察第三个函数可以发现,不管是奇数还是偶数的奇怪,都进行了2次递归调用,但这两个递归调用都是完全相同的
1 | pow3(x,n/2)*pow3(x,n/2); |
也就是说,我们可以先递归调用1次,存结果再计算!
1 | int pow4(int x,int n) |
此时函数中只调用了1次递归,每次递归之后,数据都除2,所以总共是log2(n)次
每次递归,还是一个乘法操作,时间复杂度O(1)
最终得到的时间复杂度就是O(logN)
!
The end
这才是我们需要的时间复杂度较低的算法,同时也复习了递归调用的时间复杂度计算办法
1 | 递归时间复杂度 = 递归次数 * 每次操作的负载度 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 慕雪的寒舍!
评论