1. 程式人生 > 其它 >LeetCode/快速冪

LeetCode/快速冪

實現 pow(x,n) ,即計算 x 的 n 次冪函式

1. 遞迴分治

先考慮指數正數的情況
求x的n次冪函式可以轉換成求兩個⌊n/2⌋的冪函式之積,由於兩個是相同的,運算時間直接減少一半
通過遞迴使得求解時間成為對數級,需要注意的是分別討論n的奇偶性
由於使用遞迴具有一定空間複雜度

class Solution {
public:
    double quickMul(double x, long N) {
        if (N == 0) return 1.0;//任何數的零次冪為1
        double y = quickMul(x, N / 2);//遞迴分治
        return N % 2 == 0 ? y * y : y * y * x;//考慮奇偶情況
    }
    double myPow(double x, int n) {
        long N = n;//考慮負數反轉後越界
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);//考慮指數的正負性
    }
};

2. 正向迭代

兩種演算法的本質其實還是拆解出需要用於求出指數值的2的冪級數組合,這樣就可以在不斷進行平方增長(自乘)的情況下
判斷哪些時機的值是需要的,從而使得時間複雜度為對數級
不過在遞迴的時候,2的零次方被被多次用於二分湊指數值,而在正向迭代的過程中,每一級冪指數最多隻會用一次
把指數值轉換成二進位制數,數值為1的位都是我們需要用來湊出指數的2的冪,通過這個我們可以判斷自乘過程中
哪些值是需要加入到計算最後總值的,這就是正向迭代

class Solution {
public:
    double quickMul(double x, long long N) {
        double ans = 1.0;// 貢獻的初始值為 x
        double x_contribute = x;
        // 在對 N 進行二進位制拆分的同時計算答案
        while (N > 0) {
            if (N % 2 == 1) // 如果 N 二進位制表示的最低位為 1,那麼需要計入貢獻
                ans *= x_contribute;
            // 將貢獻不斷地平方
            x_contribute *= x_contribute;
            // 捨棄 N 二進位制表示的最低位,這樣我們每次只要判斷最低位即可
            N /= 2;
        }
        return ans;
    }

    double myPow(double x, int n) {
        long long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }
};