LeetCode 50. Pow(x, n)---Java题解

题目: 实现 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
第04^5       ×       1    //奇数次幂,res=res*4;x=4^2;n=5//2116^2       ×       4    //偶数次幂,x=16^2;n=2//22256^1      ×       4    //奇数次幂,res=res*256;x=256^2;n=1//2365536^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/

猜你喜欢

转载自blog.csdn.net/weixin_44759105/article/details/109731369