题目
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例 1:
输入: 2.00000, 10
输出: 1024.00000
示例 2:
输入: 2.00000, -2
输出: 0.25000
分析
根据动态规划的填表思想:
float tb[n+1]
tb[i]表示 x^i 的值
因此 x^n = tb[n]
根据分治思想
我们考虑将n变小
根据幂的因式分解规则eg:
x^120= x^(60+60) 简记为 120=60+60
可以看出我们不需要算出tb[61]->tb[119]的值
而 60 = 30 * 30
可以看出我们不需要算出tb[31]->tb[59]的值
…
因式分解表如下
120= 60 + 60
60 = 30 + 30
30 = 15 + 15
15 = 8 + 7
8 = 4 + 4
7 = 4 + 3
…
状态转移方程
当n为双数:tb[n]=tb[n/2]*tb[n/2]
当n为单数:tb[n]=tb[n/2]*tb[n/2+1]
本例中我们需要计算出 tb[…,3,4,7,8,15,30,60,120]的值
我们创建一个栈s用来记录我们一定要计算的tb[i]
则s[0]=120 s[1]=60 s[2]=30 s[3]=15 s[4]=8 s[5]=7 s[6]=4 s[7]=3 s[top]=…
从0->top不难发现
1.如果 s[0]->s[k] 都是双数
s[k+1]=s[k]/2
2.如果 s[k]是单数,那么s[k]之后的 双数s[m]的因子是s[m]后一位的单数s[n]的因子,因此s[m]不再需要分解
例如 当k=3,s[k]=s[3]=15
m=4,n=5,s[m]=8=4+4;s[n]=7=4+3;双数s[m]的因子是4,单数s[n]的因子是4和3
所以对n的分解分为两个阶段
1.根据s[n+1]=s[n]/2直接获取s的 首部双数序列[0,k]和首个单数k+1
2.从k+1开始,使 k+2(i+1)是双数 k+1+2i是单数(i=0,1,2,3,…)
GO代码
//递归
func pow(x float64,n int) float64 {
if n&1==1{
//n单数
return pow(x,n/2)*pow(x,n/2)*x
}else{
//n双数
return pow(x,