地址:https://leetcode.com/problems/powx-n/
题目:
Implement pow(x, n)
, which calculates x raised to the power
n
(
x
n
)
n (x^n)
n(xn).
Example 1:
Input: 2.00000, 10
Output: 1024.00000
Example 2:
Input: 2.10000, 3
Output: 9.26100
Example 3:
Input: 2.00000, -2
Output: 0.25000
Explanation: 2 − 2 2^{-2} 2−2 = 1 / 2 2 1/2^2 1/22 = 1/4 = 0.25
Note:
- -100.0 < x < 100.0
- n n n is a 32-bit signed integer, within the range [ − 2 31 −2^{31} −231, 2 31 − 1 2^{31} − 1 231−1]
理解:
求
x
n
x^n
xn。应该是需要通过一些方法减少乘法的使用次数。
x
n
=
x
n
2
+
n
2
=
(
x
2
)
n
2
x^n=x^{\frac{n}{2}+\frac{n}{2}}=(x^2)^{\frac{n}{2}}
xn=x2n+2n=(x2)2n
注意截断的问题即可,即n为奇数的时候。
实现:
这种实现在C++中会溢出的
public class Solution {
public double pow(double x, int n) {
if(n == 0)
return 1;
if(n<0){
n = -n;
x = 1/x;
}
return (n%2 == 0) ? pow(x*x, n/2) : x*pow(x*x, n/2);
}
}
有很多办法可以解决这个问题,比如用更大的值去保存这个n,但是每次循环都需要重新赋值,感觉不是很优雅。。
解决方法之一是下面这种。
class Solution {
public:
double myPow(double x, int n) {
if (n == 0)
return 1.0;
double tmp = myPow(x, n / 2);
if (n % 2)
return n < 0 ? 1 / x*tmp*tmp : x*tmp*tmp;
else
return tmp*tmp;
}
};
不管符号,而是在返回的时候用1/x去乘。
非递归的方式:
这种思路更像是
x
n
=
x
n
1
+
n
2
+
⋯
+
n
k
x^n=x^{n_1+n_2+\cdots+n_k}
xn=xn1+n2+⋯+nk
其中
n
i
n_i
ni表示n的二进制表示某一位是1
比如
x
7
=
x
4
∗
x
2
∗
x
x^7=x^4*x^2*x
x7=x4∗x2∗x
class Solution {
public:
double myPow(double x, int n) {
if (n == 0)
return 1.0;
unsigned long long u= llabs(n);
double ans = 1.0;
while (u) {
if (u & 1)
ans *= x;
x *= x;
u >>= 1;
}
return n < 0 ? 1.0 / ans : ans;
}
};