题目描述
快速求幂法(利用二分思想)
Java
要注意的一点是,虽然题目中告诉我们不需要考虑大数问题,但是给出的 n 可以取到 -2147483648(int 整型负数的最小值,Java中 int变量 n∈[−2147483648,2147483647]),当 n = -2147483648 时,执行 n = -n 会因越界而赋值出错。因此,在编码的时候,需要先将 n 转换成 long 类型。
class Solution {
public double myPow(double x, int n) {
// 当底数为0 时,直接返回 0.0,避免后续求倒数时出错
if (x == 0) return 0.0;
// 先将 n存入 long变量 b,后面用 b代替 n进行操作即可。
long b = n;
// 初始化res=1,故初始状态 x^n = x^n * res
double res = 1.0;
// 当指数为负时,先将底数求倒,然后取负指数的绝对值
if (b<0){
x = 1/x;
b = -b;
}
while (b>0){
if ((b & 1)==1) // 奇数次幂时,将多出的一项乘入 res中
res *= x;
x *= x; // 偶数次幂时,求x^2,x^4,x^8,...
b >>>= 1; // 对指数不断二分, 使用无符号右移操作是为了防止溢出
}
return res;
}
}
改为递归写法
public class Solution {
public double myPow(double x, int n) {
// 特殊情况
if (x == 0) return 0.0;
if (x == 1) return 1.0;
long b = n;
if (b < 0) {
return 1 / helper(x, -b);
}
return helper(x, b);
}
private double helper(double x, long n) {
// 递归终止条件
if (n == 0) return 1.0;
if ((n % 2) == 0) { // 偶数幂的时候
double square = helper(x, n / 2);
return square * square;
} else { // 奇数幂的时候
double square = helper(x, (n - 1) / 2);
return square * square * x;
}
}
}
参考
https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/solution/mian-shi-ti-16-shu-zhi-de-zheng-shu-ci-fang-kuai-s/
https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/solution/di-gui-xie-fa-fen-zhi-si-xiang-yu-fei-di-gui-xie-f/