LeetCode题目:数值的整数次方

题目描述:

实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
示例 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] 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

首先想到的方法就是按次方数n,循环n次,如果n为负数,就将x取倒数,然后n取绝对值。在循环里面每次将结果乘以输入的数x。但是显然这种做法不可取,如果当n的值很大时,循环的次数就会很多,超出时间控制。(后面不再重复n小于零的做法,默认n是大于0的)
其次,想到的方法以2^11为例做说明:
x^9 = x^8 * x^1
在这里面,有内外两个循环,内循环只要幂数m乘以2还不大于n,就将x变为原来的平方(xx),当m乘以2大于n的时候,退出内循环,在外循环里执行res = res * x;然后n = n - m;并且把x重新回到输入时的值,再次进入内循环。如此反复知道外循环里的n = n - m得到0,终止循环,返回res。
这个是我想到的方法,但是依然没有达到系统的要求,运行超时。
答案里面提供了一个更加绝的解答:
同样以x^9为例,9的二进制位1001,可以看到下图:
在这里插入图片描述
这里只需要设置一个循环,循环里面的x只负责每次执行x = x
x,而返回值res需要执行的是res = res * x,执不执行由对应二进制数位上的值时0还是1决定,如果是0,不执行,如果是1,执行res = res * x。而对应数位上的值是不是1可以将n和1做按位与运算,如果结果为1,则最右边的数字为1,否则最右边的数字为0。每次将n右移一位,如果n为0,则循环结束。
代码(Java):

public class Solution {
	public static void main(String[] args) {
		double x = 2;
		int n = 10;
		System.out.println(myPow(x,10));
	}
	
	public static double myPow(double x, int n) {
		//0的任何次方都是0
		if(x == 0) return 0;
		long b = n;
		//初始化返回值为1 
		double res = 1;
		if(b < 0) {//如果幂数为负数,则将基数x倒置,然后幂数去绝对值
			x = 1/x;
			b = -b;
		}
		while(b > 0) {//幂数每次右移1位,当幂数还不等于0的时候,继续执行循环
			if((b & 1)==1) { //幂数的最右边的位数为1,让当前的基数乘以res赋给res
				res *= x;
			}
			x *= x; //res赋值之后,基数就变成了原来的平方
			b = b >> 1;  //幂数右移一位
		}
		return res;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值