今天通过一道难度看着很大其实一般的题目来深刻的理解一下递归和分治的思想。
题目描述:
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
题目示例:
在做这道题之前我们先看个例子:
x
64
x^{64}
x64
我们可以按照:
x
−
>
x
2
−
>
x
4
−
>
x
8
−
>
x
16
−
>
x
32
−
>
x
64
x->x^2->x^4->x^8->x^{16}->x^{32}->x^{64}
x−>x2−>x4−>x8−>x16−>x32−>x64
再
来
看
看
:
x
65
再来看看:x^{65}
再来看看:x65
我们可以按照:
x
−
>
x
2
−
>
x
4
−
>
x
8
−
>
x
16
−
>
x
32
−
>
x
64
−
>
x
65
x->x^2->x^4->x^8->x^{16}->x^{32}->x^{64}->x^{65}
x−>x2−>x4−>x8−>x16−>x32−>x64−>x65
最后一个x^65怎么来的,其实就是
x
∗
x
64
x* x^{64}
x∗x64
但是呢从左至右推导看上去很困难,因为在每一步中,我们都不知道上一步的结果平方以后需不需要额外的去乘x,但是从右至左来看,分治的思路就很明确了:
当
我
们
计
算
x
n
时
,
可
以
先
递
归
的
计
算
出
y
=
x
n
/
2
当我们计算x^n时,可以先递归的计算出y=x^{n/2}
当我们计算xn时,可以先递归的计算出y=xn/2
根
据
递
归
计
算
的
结
果
,
如
果
n
为
偶
数
,
那
么
x
n
=
y
2
,
如
果
n
为
奇
数
,
那
么
x
n
=
x
∗
y
2
。
递
归
的
边
界
为
0
根据递归计算的结果,如果n为偶数,那么x^n=y^2,\\如果n为奇数,那么x^n=x*y^2 。\\递归的边界为0
根据递归计算的结果,如果n为偶数,那么xn=y2,如果n为奇数,那么xn=x∗y2。递归的边界为0
代码如下:
public double myPow(double x, int n) {
long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
public double quickMul(double x, long N) {
if (N == 0) {
return 1.0;
}
double y = quickMul(x, N / 2);
return N % 2 == 0 ? y * y : y * y * x;
}