這道題可以利用二進制,就可以快速解決了。
原題
實現函數double Power(double base, int exponent),求base的exponent次方。不得使用庫函數,同時不需要考慮大數問題。
示例 1:
輸入: 2.00000, 10
輸出: 1024.00000
示例 2:
輸入: 2.10000, 3
輸出: 9.26100
示例 3:
輸入: 2.00000, -2
輸出: 0.25000
解釋: 2-2 = 1/2^2 = 1/4 = 0.25
說明:
-100.0 < x < 100.0
n 是 32 位有符號整數,其數值範圍是 [−2^31, 2^31 − 1] 。
原題url:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/
解題
這道題,如果你是用正常計算的話,提交之後會發現報超時,因此,肯定需要尋找捷徑的。
因爲不能使用庫函數,而且上面普通方法也是會超時的,那麼問題的關鍵就是在如何快速計算。
而如果想快的,最好的辦法就是可以利用曾經計算的結果,避免重複計算。
我一開始的想法是,比如計算 2^6 ,從數學上來說,等同於計算 4^3。但如果要用這種邏輯的話,就必須要求傳入參數 n 是 2^w(其中 w 是正整數),否則計算邏輯會比較複雜。因此放棄該方案。
二進制
重點依舊是放在利用曾經計算的結果,避免重複計算
上,那麼理想情況也就是計算 x^n 後,之後希望直接計算 x^2n,而x^2n = x^n * x^n = x^(n + n)
。
從上面的討論可以看出,計算冪,可以轉換成將指數進行合理的加法拆分。所謂合理
,就是後一個是前一個的 2 倍,這樣的話,就自然聯想到要對指數從十進制
轉爲二進制
。
7 = (111) = 1 * 2^2 + 1 * 2^1 + 1 * 2^0
9 = (1001) = 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0
當然,上面是從大到小累加,實際計算時肯定是從小到大進行累加的。
說到二進制,肯定少不了位運算,那麼計算每一位二進制上的值,有什麼快速的方法呢?
有的,利用n & 1
,求出最低位的值(0或者1),然後n >> 1
,右移,相當於移除最低位,不停循環,也就能計算出二進制上每一位的值了。
接下來看看代碼:
class Solution {
public double myPow(double x, int n) {
if (x == 0) {
return 0;
}
// 此處用long,是防止n是Integer.MIN_VALUE時,取反後直接就超過了Integer.MAX_VALUE
long b = n;
double res = 1.0;
if(b < 0) {
x = 1 / x;
b = -b;
}
while(b > 0) {
if ((b & 1) == 1) {
res *= x;
}
// 底數擴大
x *= x;
// 指數右移
b >>= 1;
}
return res;
}
}
提交OK。
總結
以上就是這道題目我的解答過程了,不知道大家是否理解了。這道題利用二進制,就可以快速解決了。
有興趣的話可以訪問我的博客或者關注我的公衆號,說不定會有意外的驚喜。
https://death00.github.io/
公衆號:健程之道
點擊此處留言