递归 求幂

来源:互联网 发布:java程序员中年 编辑:程序博客网 时间:2024/06/04 19:45

1. 迭代算法

long int pow(long int X, unsigned int N){long int val = 1;for(int i = 0; i < N; i++)val *= X;return val;}

2. 递归算法  

long int pow(long int X, unsigned int N)  {      if(N == 0)          return 1;      if(N == 1)          return X;      if( N % 2 == 0)          return pow( X * X, N / 2);      else          return pow( X * X, N / 2) * X;  } 


      递归算法原理:

               N为偶数: X^N = X^(N/2) *  X^(N/2)

               N为奇数: X^N = X^(N/2) * X^(N/2) * X

               比如 X^10 = X^5 * X^5, X^5 = X^2 * X^2 * X, X^2 = X^1 * X^1。

3. 二者比较

    (1)迭代算法需要O(1)空间复杂度,需要O(N)时间复杂度。

              需要进行N此乘法运算,而乘法又比较耗费时间。

     (2)递归算法需要O(logN)空间复杂度, O(logN)时间复杂度。

               计算X^10,我们只需要进行4次乘法操作。

4. 总结

    一般情况下,上述递归算法比迭代算法快,但是如果N很大的时候,可能会导致占用较大的空间。

 

还可以改写成:

long int pow(long int X, unsigned int N){if(N == 0)return 1;if( N % 2 == 0)return pow( X * X, N / 2);elsereturn pow( X, N -1) * X;}



进一步改进:

上述代码耗费logN的空间复杂度,将递归改成迭代,进一步降低空间。

将N用二进制表示如下:

这样,X的N次方可以表示为:

而相邻两项关系如下:


代码如下:

int pow(int X, int N){int result = 1;for( ; N ; N >>= 1){if(N & 1)result *= X;X *= X;}return result;}

空间复杂度降下来了,O(1),那现在的时间复杂度是多少? 还是O(logN) ?

logN位二进制位最大可以表示==》 N - 1,所以用logN + 1位可以表示整数N。所以,时间复杂度仍然为O(logN)。




原创粉丝点击