文章目录
- 题目:
- 解法1:暴力
- 解法2:递归
- 解法3:快速幂
- 解法4:快速幂(迭代)
题目:
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
提示:
- -100.0 < x < 100.0
- -231 <= n <= 231-1
- -104 <= xn <= 104
解法1:暴力
/**
* 思路:
* n可能是正数,负数,0
* 标记n--mark,用于最后返回时进行判断。mark是负数用1除结果
* 迭代:x乘以自身n次
*/
public double myPow(double x, int n) {
if (n == 0) return 1;
int mark = n;
if (n < 0) {
n = -n;
}
double result = 1;
for (int i = 0; i < n; i++) {
result *= x;
}
if (mark < 0) return 1 / result;
return result;
}
时间复杂度:On
空间复杂度:O1
解法2:递归
/**
* Exception in thread "main" java.lang.StackOverflowError
* at Test.recursive(Test.java:24)
* at Test.recursive(Test.java:24)
* 原因:递归的层数过多,导致线程栈溢出
*
* 思路:
* x递归的乘以自身
* 指数是负数就让结果被1除
*/
public double myPow(double x, int n) {
double result=1;
if (n<0)return 1/recursive(result,x,n);
return recursive(result,x,n);
}
private double recursive(double result, double x, int n) {
if (n==0)return 1;
if (n<0)
result=recursive(result,x,n+1);
else
result=recursive(result,x,n-1);
return result*x;
}
时间复杂度:On
空间复杂度:O1
原因:递归的层数过多,导致线程栈溢出
解法3:快速幂
/**
* 思路:
* n可能是正数,负数,0
* x^10=x^5*x^5
* x^11=x^5*x^5*x^1
* 2^10 指数除2分成 2^5 * 2^5 指数相加 2^10
* 指数如果是奇数 2^5 指数除2分成 2^2 * 2^2 少乘了一位
* 每次对平方的结果进行平方,到最后的时候判断下n次是否为偶数,非偶数在乘以 一个x
*/
public double myPow(double x, int n) {
if (n < 0)
return 1 / recursive(x, n);
return recursive(x, n);
}
private double recursive(double x, int n) {
if (n == 0) return 1;
double pow_half = recursive(x, n / 2);
return n % 2 == 0 ? pow_half * pow_half : pow_half * pow_half * x;
}
时间复杂度:Ologn
空间复杂度:O1
易犯错误:
当n等于-2147483648时转换成正数仍然是-2147483648就会出现死递归
因为会超出int范围-2147483648到2147483647
解法4:快速幂(迭代)
public double myPow(double x, int n) {
double result=1;
for (int i=n;i!=0;i/=2){
if (i%2!=0)result*=x;
x*=x;
}
return n>0?result:1/result;
}
时间复杂度:Ologn
空间复杂度:O1