1. 程式人生 > 其它 >用遞迴法將一個整數n轉化為字串_Pow(x,n)

用遞迴法將一個整數n轉化為字串_Pow(x,n)

技術標籤:用遞迴法將一個整數n轉化為字串

編號:0010
試題來源:leetcode

題目描述

實現

,即計算 次冪
其中 是32位有符號整數,其數值範圍是 ,也就是 c++int的取值範圍

示例

  • 示例1:

83f4af1c2916e8ced996a9e9321e29b2.png
  • 示例2:

619c840fc6c1d3b3658fb62d14b85b54.png
  • 示例3:

622c2c524d592011088ce1c9f2b3da41.png

解答演算法

遞迴(我的解法)

演算法思路

對於底數

來說,有特殊情況 ,此時不用判斷 直接輸出 就好。

對於指數

來說,當 的時候,不適用於遞迴表示式,直接輸出 就好

對於一般情況來說,

有兩種可能,一種是 是奇數,另一種是 是偶數,當 是偶數的時候,顯然
這裡面,顯然把 利用了兩次,這樣的話,就相對於逐個遞乘減少了一般的工作量;當 時偶數的時候,$$x^{n} = x^{frac{n}{2}}*x^{frac{n}{2}} * x$$只是在之前的基礎上多乘了一個x,計算步驟也是很小的。

然後遞迴的終止條件就是

,此時,只要返回 就好。

當計算

的時候,我用的是 ,但是這裡存在越界的可能,對於 來說,其相反數 不能用 int型別表示,因此我把式子改寫成了 這樣就避免了 越界的可能性。

實現程式碼

class Solution {
public:
    double myPow(double x, int n) {
        if (x == 1)   //當底數為1的時候,直接輸出1
            return 1;
        if (n < 0)    //當指數小於0的時候,先轉換成指數大於0的情況
            return 1 / (x * myPow(x, -(n + 1)));
        if (n == 0)   //當指數為0的時候,直接輸出1
            return 1; 
        if (n == 1)  //當指數為1的時候,遞迴終止
            return x;
        double result = myPow(x, n / 2);  //遞迴呼叫
        if (n % 2 == 0)  //偶數和結束分開討論
            return result * result;
        if (n % 2 == 1)
            return result * result * x;
        return 0;  //這個是因為程式要求一定要有返回值,所以加上的,無意義
    }
};

複雜度分析

  • 時間複雜度:每一次遞迴僅進行了一次操作,一共進行了 次遞迴,因此時間複雜度
  • 空間複雜度:整個過程中用到的空間是遞迴用到的棧空間,深度應當是 ,因此空間複雜度

這是我自己第一次兩個100%擊敗,有點意思—__—

遞迴(官方解答)

演算法思路和複雜度分析和我的一樣,不列舉了。

程式碼實現

class Solution {
public:
    double quickMul(double x, long long N) {  //指數變成N,避免了溢位問題
        if (N == 0) {  //指數為0的情況
            return 1.0;
        }
        double y = quickMul(x, N / 2);    //遞迴呼叫
        return N % 2 == 0 ? y * y : y * y * x;  //這個對奇偶的利用有點簡潔
    }

    double myPow(double x, int n) {
        long long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N); //對正負的利用
    }
};

三目運算子真好使

迭代(官方解答)

演算法思路

迭代思路用到了整數的二進位制表示,

是一個十進位制整數,它一定可以被轉化成一個二進位制數 ,那麼 ,因此 ,因此只要知道了二進位制數,可以求解其對應的

程式碼實現

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);
    }
};

複雜度分析

  • 時間複雜度:整個過程中進行了 層迴圈,因此時間複雜度為
  • 空間複雜度:顯然