實現 pow(x, n) ,即計算 x 的 n 次冪函數。
示例 1:
輸入: 2.00000, 10
輸出: 1024.00000
示例 2:
輸入: 2.10000, 3
輸出: 9.26100
示例 3:
輸入: 2.00000, -2
輸出: 0.25000
解釋: 2-2 = 1/22 = 1/4 = 0.25
說明:
-100.0 < x < 100.0
n 是 32 位有符號整數,其數值範圍是 [−231, 231 − 1] 。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/powx-n
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
九牛二虎之力寫出了又臭又長的代碼,最下面有copy評論區6的飛起的解
class Solution {
public double myPow(double x, int n) {
/**
保存[x^2, x^4, x^8.....]
n拆成二進制形式:將n依次匹配並減去已匹配的
如n=11 即爲 n=8+2+1
2^11 = (2^8)*(2^2)*(2^1)
*/
if(n == -2147483648){//不能直接去絕對值
return myPow(x,-1)*myPow(x,n+1);
}
boolean flag_x = false;
if(x==-1){//否則x=-1且n極大時候會出錯,這裏直接判斷
return n%2==0?1d:(-1d);
}
boolean flag_n = false;//冪是否爲負數
if(n == 0 || x == 1d){
return 1d;
}else if(n<0){
flag_n = true;
}
n = Math.abs(n);
int rank = 1;
double pows= x;
Map<Integer,Double> m = new HashMap<>();//可以改進爲數組或List
m.put(0,1d);
m.put(rank,pows);
while(n>=rank){//等於不要遺漏,否則會死循環
pows = pows*pows;
if(pows == 0){//中間值=0
return 0d;
}else if(pows == 1){//中間值=1
return 1d;
}else if(pows>Double.MAX_VALUE && flag_n){//分母已經極大,直接返回0
return 0;
}
rank *= 2;
m.put(rank,pows);
}
rank /= 2;
double ret = m.get(rank);
n -= rank;
while(n>0){
rank /= 2;
if(n>=rank){//等於不要遺漏,否則會死循環
ret *= m.get(rank);
n -= rank;
}
}
return flag_n?(1/ret):ret;
}
}
評論有個很強的解:思路非常6,自作主張加了註釋
class Solution {
public double myPow(double x, int n) {
double res = 1.0;
for(int i = n; i != 0; i /= 2){
//折半時 如果是偶數直接折半,如果是奇數,會丟失一個x,補齊多乘一個x
if(i % 2 != 0){//就算n是2的冪也一定會在i=1的時候觸發
res *= x;
}
x *= x;
}
return n < 0 ? 1 / res : res;
}
}