[剑指offer]数值的整数次方
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:590928
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
代码:
1 class Solution { 2 public: 3 double Power(double base, int exponent) { 4 if(exponent == 0) 5 return 1; 6 else if(exponent > 0) 7 return base*Power(base,exponent - 1); 8 else 9 return 1/base*Power(base,exponent + 1); 10 } 11 };
思路:
在这里只是考虑了指数的正负和0三种情况,递归求解,代码比较简洁。在事后对比了其余的代码之后发现确实还存在遗漏的情况:底数为0,指数为非正数的情况,应当抛出”0不能为除数“的异常(不过考虑到底数为double,判断为0的条件也应当注意)。
这里解决办法比较简单,直接加个if就可以了,但是这不是本期的重点,现在来介绍本期的核心内容:
简单快速幂
1 class Solution { 2 public: 3 double Power(double base, int exponent) { 4 long long p = abs((long long)exponent); 5 double r = 1.0; 6 while(p){ 7 if(p & 1) r *= base; 8 base *= base; 9 p >>= 1; 10 } 11 return exponent < 0 ? 1/ r : r; 12 } 13 };
惊!第一眼看到这个代码的时候,我吓了一跳,这是什么算法?后来去网上搜了下,这算法居然可以把计算幂的时间复杂度降低到O(log₂N),厉害了。
这里还提供了另一种快速计算的算法,利用了另一个性质(a*b)%p=((a%p)*(b%p))%
快速幂求余
1 int fun(int a, int b,int p) 2 { 3 int ans = 1; 4 while (a&&b) 5 { 6 if (b & 1) ans = (ans*a) % p; 7 a = (a*a) % p; 8 b >>= 1; //移位运算,右移一位 9 } 10 return ans; 11 }