题目: 实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例
输入: 2.00000, 10
输出: 1024.00000
输入: 2.10000, 3
输出: 9.26100
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
解题思路:快速幂
快速幂应用的是分治的思想
基本原理:
xn = (x2)n//2 (n为偶数) 公式1
xn = x*(x2)n//2 (n为奇数)公式2
根据推导,可以通过x=x2把幂次从n降到n//2,直到降为0。时间复杂度就降到了O(logn)。
算法流程:
设res=0,初始状态为xn=xn×res。在循环二分时,每当n为奇数时,将当前x乘入res,并降低x幂次(即用x=x2 代替);当n为偶数时,仅降低x幂次,最后当幂次将为0时,返回的res即为结果(xn=x0×res)
例子:计算4^5
初始态 x^n × res
第0轮 4^5 × 1 //奇数次幂,res=res*4;x=4^2;n=5//2
第1轮 16^2 × 4 //偶数次幂,x=16^2;n=2//2
第2轮 256^1 × 4 //奇数次幂,res=res*256;x=256^2;n=1//2
第3轮 65536^0 × 1024 //检测到n=0,返回res,即1024
判定n是否为奇数,一般使用n%2,转化为位运算n&1
对n降幂,一般使用n/2,转化为位运算n>>1
使用位运算更快
这里还要注意,n的取值范围为[-231,+231-1],由于n可以取到-231,当n=-231,计算xn,需要转化为(1/x)-n,n=+231,越界了,所以要先把n保存在一个long型变量b中,对b>>1,以免越界。
代码:
class Solution {
public double myPow(double x, int n) {
if(x==0.0d) return 0.0;
long b=n;
double res=1;
if(n<0){
x=1/x;
b=-b;
}
while(b>0){
//b为奇数 res=res*x
if((b&1)==1) res=res*x;
//降幂操作,x=x^2;b=b>>1;
x=x*x;
b=b>>1;
}
return res;
}
}
参考:https://leetcode-cn.com/problems/powx-n/solution/50-powx-n-kuai-su-mi-qing-xi-tu-jie-by-jyd/