[剑指 Offer 第 2 版第 16 题] “数值的整数次方”做题记录
- 牛客网 online judge 地址:https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述
给定一个 double 类型的浮点数 base 和 int 类型的整数 exponent 。求 base 的 exponent 次方。
求解思路与关键
注意分类讨论与与递归函数的设计。
关键:将循环变成递归操作,每次折半求值,避免死板做循环,这种感觉像加法变乘法。
注意细节:底数为 0 的时候,指数为负数是没有意义的
精确计算,转成浮点数 0.125:
System.out.println((double) 1 / 8);
- 右移 1 位运算等价于“除以 2”:
// exponent 指数,exponent >> 1 表示将指数除以 2
System.out.println(exponent >> 1);
- 使用位运算的 与 运算符代替了求余数运算,来判断一个数是奇数还是偶数:
if ((exponent & 1) == 0) {
参考解答
参考解答1:
public class Solution {
public double Power(double base, int exponent) {
// 先把极端情况考虑到
// 不能用 == 比较两个浮点数是否相等,因为有误差
if (equals(base, 0) && exponent < 0) {
throw new IllegalArgumentException("当底数为 0 的时候,指数为负数没有意义");
}
if (exponent == 0) {
return 1.0;
}
// 下面将指数的两种情况合并成一种情况考虑
if (exponent > 0) {
return power(base, exponent);
} else {
return power(1 / base, -exponent);
}
}
public double power(double base, int exponent) {
if (exponent == 0) {
return 1.0;
}
if (exponent % 2 == 0) {
double square = power(base, exponent / 2);
return square * square;
} else {
double square = power(base, (exponent - 1) / 2);
return square * square * base;
}
}
private boolean equals(double num1, double num2) {
return num1 - num2 < 0.000001 && num1 - num2 > -0.000001;
}
}
参考解答2:
public class Solution {
public double Power(double base, int exponent) {
if (exponent == 0) {
return 1;
}
if (exponent < 0) {
return 1 / Power(base, -exponent);
}
// 使用位运算的 与 运算符代替了求余数运算,来判断一个数是奇数还是偶数
if ((exponent & 1) == 0) {
double square = Power(base, exponent >> 1);
return square * square;
} else {
double square = Power(base, (exponent - 1) >> 1);
return square * square * base;
}
}
public static void main(String[] args) {
int base = 3;
int exponent = -3;
Solution solution = new Solution();
double result1 = solution.Power(base, exponent);
System.out.println(result1);
exponent = 6;
double result2 = solution.Power(base, exponent);
System.out.println(result2);
// exponent 指数,exponent >> 1 表示将指数除以 2
System.out.println(exponent >> 1);
}
}