50. Pow(x, n)
程序员文章站
2022-07-15 12:47:51
...
题目描述(中等难度)
就是求幂次方。
解法一
求幂次方,用最简单的想法,就是写一个 for 循环累乘。
至于求负幂次方,比如 2^(-10) ,可以先求出 2^(10) ,然后取倒数,1/2^(10) ,就可以了。
double mul = 1;
if (n > 0) {
for (int i = 0; i < n; i++) {
mul *= x;
}
} else {
n = -n;
for (int i = 0; i < n; i++) {
mul *= x;
}
mul = 1 / mul;
}
但这样的话会出问题,问题出在 n = - n 上,因为最小负数 -2^(31)取相反数的话,按照计算机的规则,依旧是 -2^(31) ,所以这种情况需要单独讨论一下。
if (n == -2147483648) {
return 0;
}
当然,这样做的话 -1 ,和 1 也需要单独讨论下,因为他们的任意次方都是 1 或者 -1 。
if (x == -1) {
if ((n & 1) != 0) { //按位与不等于 0 ,说明是奇数
return -1;
} else {
return 1;
}
}
if (x == 1.0)
return 1;
综上,代码就出来了。
public static double myPow(double x, int n) {
if (x == -1) { //按位与不等于 0 ,说明是奇数
if ((n & 1) != 0) {
return -1;
} else {
return 1;
}
}
if (x == 1.0)
return 1;
if (n == -2147483648) {
return 0;
}
double mul = 1;
if (n > 0) {
for (int i = 0; i < n; i++) {
mul *= x;
}
} else {
n = -n;
for (int i = 0; i < n; i++) {
mul *= x;
}
mul = 1 / mul;
}
return mul;
}
public static void main(String args[]) {
double x=2;
int n=3;
double ans=myPow(x,n);
System.out.println(ans);
}
时间复杂度:O(n)。
空间复杂度:O(1)。
但是在leetcode上这种方法已经超出时间限制。
解法二 递归
对于上边的解法,太慢了。可以优化下。乘法的话,我们不用一次一次的相乘,得到 2 次方后,我们可以直接把 2 次方的结果相乘,就可以得到 4 次方,得到 4 次方的结果再相乘,就是 8 次方了,这样的话就会快很多了。
直接利用递归吧
对于 n 是偶数的情况, 。
对于 n 是奇数的情况, 。
public class Pow_x_n2 {
public double powRecursion(double x, int n) {
if (n == 0) {
return 1;
}
//偶数的情况
if ((n & 1) == 0) {
double temp = powRecursion(x, n / 2);
return temp * temp;
} else { //奇数的情况
double temp = powRecursion(x, n / 2);
return temp * temp * x;
}
}
public double myPow(double x, int n) {
if (x == -1) {
if ((n & 1) != 0) {
return -1;
} else {
return 1;
}
}
if (x == 1.0) return 1;
if (n == -2147483648) return 0;
double mul = 1;
if (n > 0) {
mul = powRecursion(x, n);
} else {
n = -n;
mul = powRecursion(x, n);
mul = 1 / mul;
}
return mul;
}
}
时间复杂度:O(log(n))。
上一篇: 50. Pow(x, n)