一【题目类别】
- 数学
二【题目难度】
- 中等
三【题目编号】
- 50.Pow(x, n)
四【题目描述】
- 实现 p o w ( x , n ) pow(x, n) pow(x,n) ,即计算 x x x 的整数 n n n 次幂函数(即, 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 / 2 2 1/2^{2} 1/22 = 1/4 = 0.25$
六【解题思路】
- 使用快速幂算法解决此题,我们可以将
x
n
x^{n}
xn拆解计算,以提高运算速度,可将
x
n
x^{n}
xn拆解为如下形式(//表示向下取整):
x n = { ( x 2 ) n / / 2 , n 为偶数 x ( x 2 ) n / / 2 , n 为奇数 x^{n}=\left\{\begin{array}{ll} \left(x^{2}\right)^{n / / 2} & , n \text { 为偶数 } \\ x\left(x^{2}\right)^{n / / 2} & , n \text { 为奇数 } \end{array}\right. xn={(x2)n//2x(x2)n//2,n 为偶数 ,n 为奇数 - 可以注意到,每次我们只需要将 x x x更新为原来的二次方,指数 n n n变为原来的一半,这样与 x n x^{n} xn是相等的,但是减少了运算的次数,降低了时间复杂度,但是需要注意如果 n n n是奇数时,需要多乘一次 x x x,因为是向下取整。
- 有了以上思路后,就可以撰写代码了,整个算法流程如下:
- 初始化 r e s = 1 res = 1 res=1,目的是记录最后一次计算的值,以及当 n n n为奇数时,作为中间变量多乘一次 x x x
- 因为题目给定的测试用例包括负指数,所以当指数 n n n是负数的时候,将问题转为大于等于0的情况计算,具体包括将 n n n变为正数或0,再将 x x x变为 1 x \frac{1}{x} x1,这在数学中显而易见,不再解释
- 当指数
n
n
n不是0的时候就继续循环,如果是0,表示都已经运算结束了,退出循环即可。在循环内部算法流程如下:
- n & 1 n \& 1 n&1表示判断当前指数 n n n是否是奇数, n & 1 = 1 n \& 1 = 1 n&1=1表示是奇数,用 r e s res res多乘一次 x x x就可以;否则表示是偶数,不用多乘一次 x x x
- 不管是奇数还是偶数,都要进行 x = x ∗ x x = x * x x=x∗x这步,表示将 x x x更新为原来的二次方
- 刚才已经将 x x x更新为原来的二次方,下一步就要将指数 n n n变为原来的一半,这样才可以和 x n x^{n} xn相等。在这里我使用的是位运算右移一位(>>1),当然,使用除法(/)直接除以2也可以
- 最后返回结果即可
七【题目提示】
- − 100.0 < x < 100.0 -100.0 < x < 100.0 −100.0<x<100.0
- − 2 31 < = n < = 2 31 − 1 -2^{31} <= n <= 2^{31}-1 −231<=n<=231−1
- n 是一个整数 n 是一个整数 n是一个整数
- − 1 0 4 < = x n < = 1 0 4 -10^{4} <= x^{n} <= 10^{4} −104<=xn<=104
八【时间频度】
- 时间复杂度: O ( l o g n ) O(logn) O(logn),其中 n n n为传入的底数参数的大小
- 空间复杂度: O ( 1 ) O(1) O(1)
九【代码实现】
- Java语言版
class Solution {
public double myPow(double x, int n) {
if(x == 0.0){
return x;
}
long b = n;
double res = 1.0;
if(b < 0){
b = -b;
x = 1 / x;
}
while(b > 0){
if((b & 1) == 1){
res *= x;
}
x *= x;
b >>= 1;
}
return res;
}
}
- C语言版
double myPow(double x, int n)
{
double res = 1.0;
if(n < 0)
{
x = 1 / x;
}
while(n != 0)
{
if((n & 1) == 1)
{
res = res * x;
}
x = x * x;
n = n / 2;
}
return res;
}
- Python版
class Solution:
def myPow(self, x: float, n: int) -> float:
res = 1
if n < 0:
n = -n
x = 1 / x
while n:
if n & 1:
res *= x
x *= x
n >>= 1
return res
十【提交结果】
-
Java语言版
-
C语言版
-
Python语言版