用遞迴法將一個整數n轉化為字串_Pow(x,n)
阿新 • • 發佈:2021-01-04
技術標籤:用遞迴法將一個整數n轉化為字串
編號:0010
試題來源:leetcode
題目描述
實現
,即計算 的 次冪其中 是32位有符號整數,其數值範圍是 ,也就是c++
中int
的取值範圍
示例
- 示例1:
- 示例2:
- 示例3:
解答演算法
遞迴(我的解法)
演算法思路
對於底數
來說,有特殊情況 ,此時不用判斷 直接輸出 就好。對於指數
來說,當 的時候,不適用於遞迴表示式,直接輸出 就好對於一般情況來說,
有兩種可能,一種是 是奇數,另一種是 是偶數,當 是偶數的時候,顯然然後遞迴的終止條件就是
,此時,只要返回 就好。當計算
的時候,我用的是 ,但是這裡存在越界的可能,對於 來說,其相反數 不能用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);
}
};
複雜度分析
- 時間複雜度:整個過程中進行了 層迴圈,因此時間複雜度為
- 空間複雜度:顯然