leetcode50.Pow(x,n)——学习笔记

题目:力扣icon-default.png?t=M0H8https://leetcode-cn.com/problems/powx-n/

不讲武德版:

class Solution {
    public double myPow(double x, int n) {
        return Math.pow(x,n);
    }
}

 leetcode50.Pow(x,n)——学习笔记_第1张图片

思路:直接使用java的内置的数学方法解题,这么写完感觉对不住leetcode给的“中等难度”。然后又自己写了一版“面向测试例子的编程”。

面向测试用例编程版:

class Solution {
    public double myPow(double x, int n) {
        boolean flag = false;
        double temp = 1;
        if(x==1){
            return 1;
        }
        if(n==-2147483648){
            if(x>0){
                return 0;
            }else if(x<0){
                return 1;
            }
        }
        if(n==2147483647 && x<1){
            if(x<1 && x>0){
                return 0;
            }else if(x<0){
                return -1;
            }    
        }
        if(n >= 0){
            flag = true;
        }
        n = Math.abs(n);
        if(n==0){
            return 1;
        }else{
            for(int i=1;i<=n;i++){
                temp = temp*x;
            }
        }
        if(flag){
            return temp;
        }else{
            return 1/temp;
        }
    }
}

 leetcode50.Pow(x,n)——学习笔记_第2张图片

思路:正正经经循环去执行的的话,总有一些n奇大无比的例子会让我执行超时,于是一气之下便把所有奇怪的测试用例都枚举出来,题目是AC通过了,但是自己心里过不去,于是学习了题解快速幂的解法。


(以上就当笑话,下面才是认真的笔记)


class Solution {
    public double myPow(double x, int n) {
        boolean flag = true;
        if(n<0){
            flag = false;
        }
        n = Math.abs(n);
        if(flag){
            return quickMul(x,n);
        }else{
            return 1/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;
    }
}

 leetcode50.Pow(x,n)——学习笔记_第3张图片

思路:之前尝试过正正经经一个一个去乘的方法,但遇到n为很大的数的时候会超出时间限制。因此我们需要一个更快的方法。前面提到“一个一个”去乘的方法是让指数逐一增加,如果让指数两倍两倍的增加则可以让执行时间减短。

1.递归的方法。当N为0时,是递归方法的出口,返回1。每一次递到下一层的时候,N都/2,直至递归出口。因为每层递下来时N都是减半的,因此归上去的时候,判断N是否能被2整除(要么被2整除,要么余数为1)。当N能被2整除的时候,y*y即表示让指数两倍增加;当N不能被2整除的时候(即余数为1),在y*y的基础上,还需要再乘一个x(补回余数1)。

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;
}

2.在主方法中,先判断n的正负号,然后去n的绝对值方便后续递归调用。

boolean flag = true;
if(n<0){
    flag = false;
}
n = Math.abs(n);

3.根据正负号判断返回值,若n为正号则直接返回quicMul()方法的返回值,若n为负号则需要在上述答案基础上取倒数。

if(flag){
    return quickMul(x,n);
}else{
    return 1/quickMul(x,n);
}

你可能感兴趣的:(Leetcode练习,leetcode,递归算法,算法,java,快速幂)