LeetCode C++ 50. Pow(x, n)【Recursion】中等

memcpy0發表於2020-11-26

Implement pow(x, n), which calculates x raised to the power n (i.e. xn).

Example 1:

Input: x = 2.00000, n = 10
Output: 1024.00000

Example 2:

Input: x = 2.10000, n = 3
Output: 9.26100

Example 3:

Input: x = 2.00000, n = -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25

Constraints:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • -104 <= xn <= 104

題意:實現函式 double Power(double base, int exponent) ,求 baseexponent 次方。不得使用庫函式,同時不需要考慮大數問題。


雖然不用考慮大數問題,但這不是意味著簡單遞迴/迭代乘法,就能夠完成這一道題——比如 1.00000 2147483647 ,順序相乘絕對會超時。

解法1 遞迴快速冪

class Solution { 
public:
    double myPow(double x, int n) { 
        if (n == 0) return 1; //正數右移最後得到0
        if (n == 1) return x;
        if (n == -1) return 1 / x; //負數右移永遠是負數,加一個判斷
        double temp = myPow(x, n >> 1);
        if (n & 1) return temp * temp * x;
        else return temp * temp;
    }
};

執行效率如下:

執行用時:0 ms, 在所有 C++ 提交中擊敗了100.00% 的使用者
記憶體消耗:6.1 MB, 在所有 C++ 提交中擊敗了28.57% 的使用者

或者寫成:

class Solution { 
public:
    double myPow(double x, int n) { 
        if (n == 0) return 1; //正數右移最後得到0
        if (n == 1) return x;
        if (n == -1) return 1 / x; //負數右移永遠是負數 
        if (n & 1) return myPow(x, n - 1) * x;
        double temp = myPow(x, n >> 1);
        return temp * temp;
    }
};

解法2 迭代快速冪

class Solution { 
public:
    double myPow(double x, int n) { 
        double ans = 1, base = x;
        bool flag = (n >= 0);
        //負數取反,考慮到最小負數,需要先自增,後續再多除一個x
        if (!flag) n = -(++n); //或者使用longlong
        while (n) {
            if (n & 1) ans *= base;
            base *= base;
            n >>= 1; //n必須取正
        }
        return flag ? ans : 1 / ans / x;
    }
};

執行效率如下:

執行用時:0 ms, 在所有 C++ 提交中擊敗了100.00% 的使用者
記憶體消耗:6.1 MB, 在所有 C++ 提交中擊敗了20.39% 的使用者

或者一開始 n 不取正,而是使用 / 2 代替右移,這樣不論正負 n 最終都會縮小到 0

class Solution { 
public:
    double myPow(double x, int n) { 
        double ans = 1, base = x;
        bool flag = (n >= 0);
        while (n) {
            if (n & 1) ans *= base;
            base *= base;
            n /= 2; //換成/2,不用擔心負數問題
        }
        return flag ? ans : 1 / ans;
    }
};

執行效率如下:

執行用時:0 ms, 在所有 C++ 提交中擊敗了100.00% 的使用者
記憶體消耗:6.3 MB, 在所有 C++ 提交中擊敗了8.13% 的使用者

相關文章