50. Pow(x, n)

题目描述(中等难度)

在这里插入图片描述
就是求幂次方。

解法一

求幂次方,用最简单的想法,就是写一个 for 循环累乘。

至于求负幂次方,比如 2^(-10) ,可以先求出 2^(10) ,然后取倒数,1/2^(10) ,就可以了。

double mul = 1;
if (n > 0) {
    for (int i = 0; i < n; i++) {
        mul *= x;
    }
} else {
    n = -n;
    for (int i = 0; i < n; i++) {
        mul *= x;
    }
    mul = 1 / mul;
}

但这样的话会出问题,问题出在 n = - n 上,因为最小负数 -2^(31)取相反数的话,按照计算机的规则,依旧是 -2^(31) ,所以这种情况需要单独讨论一下。

if (n == -2147483648) {
    return 0;
}

当然,这样做的话 -1 ,和 1 也需要单独讨论下,因为他们的任意次方都是 1 或者 -1 。

if (x == -1) {
    if ((n & 1) != 0) { //按位与不等于 0 ,说明是奇数
        return -1;
    } else {
        return 1;
    }
}
if (x == 1.0)
    return 1;

综上,代码就出来了。

public static double myPow(double x, int n) {
		
	    if (x == -1) { //按位与不等于 0 ,说明是奇数
	        if ((n & 1) != 0) {
	            return -1;
	        } else {
	            return 1;
	        }
	    }
	    if (x == 1.0)
	        return 1;

	    if (n == -2147483648) {
	        return 0;
	    }
	    
	    double mul = 1;
	    if (n > 0) {
	        for (int i = 0; i < n; i++) {
	            mul *= x;
	        }
	    } else {
	        n = -n;
	        for (int i = 0; i < n; i++) {
	            mul *= x;
	        }
	        mul = 1 / mul;
	    }
	    return mul;
	}
	public static void main(String args[]) {
		double x=2;
		int n=3;
		double ans=myPow(x,n);
		System.out.println(ans);
	}

时间复杂度:O(n)。

空间复杂度:O(1)。

但是在leetcode上这种方法已经超出时间限制。

解法二 递归

对于上边的解法,太慢了。可以优化下。乘法的话,我们不用一次一次的相乘,得到 2 次方后,我们可以直接把 2 次方的结果相乘,就可以得到 4 次方,得到 4 次方的结果再相乘,就是 8 次方了,这样的话就会快很多了。

直接利用递归吧

对于 n 是偶数的情况, x n = x n / 2 ∗ x n / 2 x^{n}=x^{n / 2} * x^{n / 2} xn=xn/2xn/2

对于 n 是奇数的情况, x n = x n / 2 ∗ x n / 2 ∗ x x^{n}=x^{n / 2} * x^{n / 2} * x xn=xn/2xn/2x

public class Pow_x_n2 {
	
	public double powRecursion(double x, int n) {
		
	    if (n == 0) {
	        return 1;
	    }
	    //偶数的情况
	    if ((n & 1) == 0) { 
	        double temp = powRecursion(x, n / 2);
	        return temp * temp;
	    } else { //奇数的情况
	        double temp = powRecursion(x, n / 2);
	        return temp * temp * x;
	    }
	}

	public double myPow(double x, int n) {
		
	    if (x == -1) {
	        if ((n & 1) != 0) {
	            return -1;
	        } else {
	            return 1;
	        }
	    }
	    if (x == 1.0) return 1;

	    if (n == -2147483648) return 0;
	    
	    double mul = 1;
	    if (n > 0) {
	        mul = powRecursion(x, n);
	    } else {
	        n = -n;
	        mul = powRecursion(x, n);
	        mul = 1 / mul;
	    }
	    return mul;
	}
}

时间复杂度:O(log(n))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值