Implement pow(x, n).
分析
该题目首先想到可以使用recursion去做,需要考虑一个陷阱,当 n 为 INT_MIN,反转会溢出
1 2 3 4 5 6 7 8 9 10 11 | class Solution { public : double myPow( double x, int num) { long n = num; if (n == 0) return 1; x = n > 0 ? x : 1.0/x; n = n > 0 ? n : -n; return n&1 ? x*myPow(x, n - 1) : myPow(x*x, n/2); } }; |
因为是tail recursion,所以可以改写成 while 循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Solution { public : double myPow( double x, int num) { long n = num; if (n == 0) return 1; x = n > 0 ? x : 1.0/x; n = n > 0 ? n : -n; double ans = 1; while (n > 0){ if (n&1) ans*=x; x*=x; n/=2; } return ans; } }; |
可以保证 n 不溢出算法
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Solution { public : double myPow( double x, int n) { if (n == 0) return 1; double t = myPow(x, n/2); if (n&1){ //odd return n > 0 ? x*t*t : 1.0/x * t * t; } else { //even return t*t; } } }; |
还有一种基于 位 操作的算法
我们现在求 xn,把 n 写成 32 bit的形式,比如
...10010
实际上对应的是
...16*1 + 8*0 + 4*0 + 2*1 + 1*0
所以 x 的任意次方,都可以写成由这些基本次方系数相乘的形式,所以可以使用查表方式得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Solution { public : double myPow( double x, int n) { if (n == 0) return 1; if (n < 0) x = 1.0 / x; unsigned int mn = n < 0 ? -n : n; double bt[32] = {x}; for ( int i = 1; i < 32; ++i){ bt[i] = bt[i - 1] * bt[i - 1]; } double result = 1; for ( int i = 0; i < 32; ++i){ if (mn & (1<<i)) result *= bt[i]; } return result; } }; |