LeetCode 第 50 題 (Pow(x, n))

liyuanbhu發表於2016-04-23

LeetCode 第 50 題 (Pow(x, n))

Implement pow(x, n).

這個題目非常簡短,求 xn

x^n
。其中n
n
為整數。
最簡單的想法就是用一個迴圈,將 x
x
自乘n
n
次。按照這個思路有下面的程式碼。

class Solution 
{
public:
    double myPow(double x, int n) 
    {
        int sign = 1;
        if(n < 0)
        {
            n = -n;
            sign = -1;
        }
        double ret = 1;
        for(int i = 0; i < n; i++)
        {
            ret = ret * x;
        }
        if(sign == -1)
        {
            ret = 1 / ret;
        }
        return ret;
    }
};

這個程式碼雖然從原理上是正確的,但是當n

n
比較大時執行速度實在是太慢。這樣提交的話肯定會執行超時。
所以我們要想點其他的辦法。

我們知道 xn1+n2=xn1×xn2

x^{n_1 + n_2} = x^{n_1} \times x^{n_2}
。如果 xn1
x^{n_1}
xn2
x^{n_2}
很容易算出來的話這樣比直接算xn1+n2
x^{n_1 + n_2}
要快速。


n=i=031ci×2i
n = \sum_{i=0}^{31} c_i \times 2^i

x2
x^2
, x4
x^4
, x16
x^{16} \ldots
這樣的數字很容易計算的。所以我們可以利用這個特點來加快計算。下面是程式碼:
double myPow(double x, int n) 
{
    double table[32];
    int sign;
    table[0] = x;
    for(int i = 1; i < 32; i++)
    {
        table[i] = table[i - 1] * table[i - 1];
    }
    if(n < 0)
    {
        n = -n;
        sign = -1;
    }
    double ret = 1;
    int i = 0;
    while(n)
    {
        if(n & 1) ret = ret * table[i];
        n = (unsigned int)n >> 1;
        i ++;
    }
    if(sign == -1)
    {
        ret = 1 / ret;
    }
    return ret;
}

這個程式碼還有一處需要特別解釋解釋。

n = (unsigned int)n >> 1;

為什麼這裡要加上 “(unsigned int)”? 只是為了應對一個特殊條件,就是 n=2147483648

n = -2147483648
,這個數是最小的 int 型變數(INT_MIN),n
-n
不在 int 型變數所能表示的數字範圍內,n=2147483648
-n = -2147483648

對於負數,n=n>>1

n = n >> 1
之後 n
n
的最高位還是 1
1

所以當 n=2147483648
n = -2147483648
時,下面這個迴圈是死迴圈。

while(n)
{
    n = n >> 1;
}

所以這裡要將 n 轉換為 unsigned int 型別。

上面的程式碼還可以再優化一點。我們可以原地計算上面程式碼中用到的那個 Table。下面是程式碼。

double myPow(double x, int n) 
{
    int sign;
    if(n < 0)
    {
        n = -n;
        sign = -1;
    }
    double ret = 1;
    while(n)
    {
        if(n & 1) ret = ret * x;
        x = x * x;
        n = (unsigned int)n >> 1;
    }
    if(sign == -1)
    {
        ret = 1 / ret;
    }
    return ret;
}

相關文章