【LeetCode-数学】Pow(x, n)
题目描述
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
输入: 2.00000, 10
输出: 1024.00000
输入: 2.10000, 3
输出: 9.26100
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:
- -100.0 < x < 100.0
- n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]
题目链接: https://leetcode-cn.com/problems/powx-n/
思路1
暴力求解。直接循环即可,需要注意 n<0 时,需要将 x=1/x 以及 n=-n. 代码如下:
class Solution {
public:
double myPow(double x, int n) {
if(n==0) return 1;
long N = n;
double ans = 1;
if(N<0){
x = 1/x;
N = -N;
}
for(int i=0; i<n; i++) ans*=x;
return ans;
}
};
// 超时
要先把 n 转为 long,因为虽然 -2^31 在 int 范围内,但 2^31 超出了 int 的范围。由于 n 的范围是 [−2^31, 2^31 − 1] ,所以该解法超时未通过。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
思路2
因为:
- \(x^n = x^{n/2}*x^{n/2}\),n 为偶数;
- \(x^n = x^{n/2}*x^{n/2}*n\),n 为奇数;
所以可以使用递归来做,类似于用递归写阶乘的方法:
class Solution {
public:
double myPow(double x, int n) {
if(n==0) return 1;
long N = n;
if(N<0){
x = 1/x;
N = -N;
}
return fastPow(x, N);
}
double fastPow(double x, int n){
if(n==0) return 1;
double half = fastPow(x, n/2);
if(n%2==0) return half * half;
else return half * half * x;
}
};
这种方法被称为快速幂。这样写也行:
class Solution {
public:
double myPow(double x, int n) {
if(n==0 || x==1) return 1;
bool isNegative = n<0?true:false;
n = abs(n);
double ans = fastPow(x, n);
if(isNegative) return 1/ans;
else return ans;
}
double fastPow(double x, int n){
if(n==0) return 1;
if(n==1) return x;
double half = fastPow(x, n/2);
if(n%2==0) return half*half;
else return half*half*x;
}
};
需要注意的是,fastPow
不能写成如下形式:
double fastPow(double x, int n){
if(n==0) return 1;
if(n%2==0) return fastPow(x, n/2)*fastPow(x, n/2);
else return fastPow(x, n/2)*fastPow(x, n/2)*x;
}
上面的写法会重复计算fastPow(x, n/2)
从而导致超时。
- 时间复杂度:O(logn)
- 空间复杂度:O(1)