0 题目描述
leetcode原题:剑指 Offer 16. 数值的整数次方
1 快速幂解法
快速幂实际上是二分思想的一种应用。
二分推导:
x
n
=
x
n
/
2
×
x
n
/
2
=
(
x
2
)
n
/
2
,
x^{n}=x^{n / 2} \times x^{n / 2}=\left(x^{2}\right)^{n / 2},
xn=xn/2×xn/2=(x2)n/2, 令
n
/
2
n / 2
n/2 为整数, 则需要分为奇偶两种情况(设向下取整除 法符号为 "
/
/
"
/ / "
//" ) :
∘
\circ
∘ 当
n
n
n 为偶数:
x
n
=
(
x
2
)
n
/
/
2
x^{n}=\left(x^{2}\right)^{n / / 2}
xn=(x2)n//2;
∘
\circ
∘ 当
n
n
n 为奇数:
x
n
=
x
(
x
2
)
n
/
/
2
,
x^{n}=x\left(x^{2}\right)^{n / / 2},
xn=x(x2)n//2, 即会多出一项
x
x
x;
算法流程:
- 当 x = 0 x=0 x=0 时:直接返回 0 (避免后续 x = 1 / x x=1 / x x=1/x 操作报错 ) ) ) 。
- 初始化 r e s = 1 \mathrm{res}=1 res=1;
- 当 n < 0 n<0 n<0 时:把问题转化至 n ≥ 0 n \geq 0 n≥0 的范围内,即执行 x = 1 / x , n = − n x=1 / x, n=-n x=1/x,n=−n;
- 循环计算:当
n
=
0
n=0
n=0 时跳出
- 当 n & 1 = 1 n \& 1=1 n&1=1 时:将当前 x x x 乘入 r e s ( r e s \quad( res( 即 r e s ∗ = x ) r e s *=x) res∗=x);
- 执行 x = x 2 ( x=x^{2} \quad( x=x2( 即 x ∗ = x ) x *=x) x∗=x);
- 执行 n n n 右移一位 (即 n > > = 1 n>>=1 n>>=1 ) 。
- 返回 r e s r e s res 。
class Solution:
def myPow(self, x: float, n: int) -> float:
if x == 0: return 0
res = 1
if n < 0:
x, n = 1 / x, -n
while n:
if n & 0x1: res *= x
x *= x
n >>= 1
return res
递归解法:
(注意:0的0次方在数学上没有意义,而且0没有倒数)
class Solution:
def myPow(self, x: float, n: int) -> float:
if x == 0: return 0
if n >= 0:
return self.power(x, n)
return self.power(1/x, -n)
def power(self, x: float, n: int):
if n == 0: return 1
r = self.power(x, n // 2)
if n & 1:
return r*r*x
return r*r
复杂度分析:
时间复杂度:
O
(
log
2
N
)
O(\log _2 N)
O(log2N) ,二分的时间复杂度为对数级别。
空间复杂度:
O
(
N
)
O(N)
O(N),递归写法有一个栈空间。