50. Pow(x, n)

Implement pow(xn).

分析

该题目首先想到可以使用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;
    }
};




posted @ 2017-02-13 16:45  copperface  阅读(210)  评论(0编辑  收藏  举报