题目:
Implement pow(x, n).
题意:
实现pow(x, n)函数;
思路一:
最容易想到的方法就是递归调用方法求n个x的乘积,注意考虑n的正负号,时间复杂度为O(n);
代码:Runtime Error 因为时间复杂度是O(n)。对于较大的n这是不可接受的。
class Solution { public: double myPow(double x, int n) { if(n==0) return 1.0; if(n<0) return 1.0/myPow(x,-n); return x*myPow(x,n-1); } };
思路二:
二分法,将n次幂二分成两部分分别计算,可以对以上算法进行改进,从而得到一种时间复杂度为O(logn)的算法。
代码: Wrong Answer 还是会溢出
class Solution { public: double myPow(double x, int n) { if(n == 0) return 1; if(n<0){ n = -n; x = 1/x; } return (n%2 == 0) ? myPow(x*x, n/2) : x*myPow(x*x, n/2); } }; </span>
思路三:
利用位操作代替除法运算。同样类似于二分法。该方法通过扫描n的二进制表示形式里不同位置上的1,来计算x的幂次
class Solution { public: double myPow(double x, int n) { if(n == 0) return 1.0; if(n<0){ n = -n; x = 1.0/x; } double ans = 1.0; while (n>0) { if (n&1) ans *= x; x *= x; n >>= 1; } return ans; } };
思路四:
为了正确计算x的n次幂,还需要考虑到以下一些情况:
1) x取值为0时,0的正数次幂是1,而负数次幂是没有意义的;判断x是否等于0不能直接用“==”。
2) 对于n取值INT_MIN时,-n并不是INT_MAX,这时需要格外小心。
3) 尽量使用移位运算来代替除法运算,加快算法执行的速度。
代码:6ms
class Solution { public: double myPow(double x, int n) { if(n<0) { if(n==INT_MIN) //处理以上情况2 return 1.0 / (pow(x,INT_MAX)*x); else return 1.0 / pow(x,-n); } if(n==0) return 1.0; double ans = 1.0 ; for(;n>0; x *= x, n>>=1) { if(n&1>0) ans *= x; } return ans; } };
思路五:
位操作
代码:4ms
class Solution { public: double myPow(double x, int n) { bitset<32> bit(abs(n)); double result = 1; for(int i = bit.size()-1; i >= 0; i--) { result*=result; if(bit[i] == 1) result *=x; } return (n >= 0)?result : 1/result; } };