二分法快-LeetCode50-Pow(x, n)

题目

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:

-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

思路1

普通思路,n个x相乘。超时。

代码1

class Solution {
    public double myPow(double x, int n) {
        if(n==0){
            return 1;
        }
        double res=0;
        if(n>0){
            res=x;
            for(int i=1;i<n;i++){
                res=res*x;
            }
        }else{
            n=-n;
            res=x;
            for(int i=1;i<n;i++){
                res=res*x;
            }
            res=1/res;
        }
        return res;
    }
}

思路2

翻倍。类似https://blog.csdn.net/qq_36025975/article/details/83685382。超时。

代码2

class Solution {
    public double myPow(double x, int n) {
        if(n==0){
            return 1;
        }
        if(x==1){
            return 1;
        }
        
        long nn=0;
        if(n>0){
            nn=n;
        }else{
            nn=-n;
        }
        
        double res=1;
        
        double mul=x;
        long count=1;
        while(true){
            if(nn==0){
                break;
            }
            if(count+count<nn){
                mul=mul*mul;
                count=count+count;
            }else{
                res=res*mul;
                
                nn=nn-count;
                mul=x;
                count=1;
            }
        }
        if(n<0){
            res=1/res;
        }
        return res;
    }
}

思路3

递归。二分。n个x相乘=(n/2个x相乘)X (n/2个x相乘)。

代码3

class Solution {
    public double myPow(double x, int n) {
        // 为防止溢出,使用long类型
        long nn=0;
        if(n==0){
            return 1;
        }else if(n>0){
            nn=(long)n;
        }else{
            // 有溢出可能,所以使用long类型
            nn=-(long)n;
        }
        
        double res=0;
        double myPow=myPow(x,(int)(nn/2));
        if(nn%2==0){
            // 这种写法超时,应改为下面语句的写法
            // res=myPow(x,(int)(nn/2)) * myPow(x,(int)(nn/2));
            res=myPow * myPow;
        }else{
            res=myPow * myPow * x;
        }
        
        if(n<0){
            res=1/res;
        }
        return res;
    }
}

关键

1.二分法快。

2.int有溢出可能时使用long。

3.

        double myPow=myPow(x,(int)(nn/2));
        if(nn%2==0){
            // 这种写法超时,应改为下面语句的写法
            // res=myPow(x,(int)(nn/2)) * myPow(x,(int)(nn/2));
            res=myPow * myPow;
        }else{
            res=myPow * myPow * x;
        }

4.思路2也是二分法但是需要多次使用二分,思路3二分法只需使用一次,所以思路2超时思路3不超时。

猜你喜欢

转载自blog.csdn.net/qq_36025975/article/details/83780634