实现 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;
}
}