java--快速幂

        今天刷lintcode的时候看到一道题,快速求幂的,即求
                         

       常规方法是如下:

while(b-- > 0){
      a  *= a;
}
return a;

      他的复杂度是O(N)。

       还有一种更有效率的做法,利用二进制(强大的二进制,如果涉及到int处理,最好先看看能不能使用二进制):

        首先,对于任意的int   n都有:
              

 
         那么自然,

 

其中p(n) = 1或0       是不是感觉很熟悉,从0遍历 到i-1就可以了。。。。

写一下代码就是:

             public int power(int a,int n){
		if (n == 0) {
			return 1 ;
		}
		if (n == 1) {
			return a ;
		}
                //利用递归方法,递归i-1次计算
		int temp = power(a, n >> 1);
		temp = temp * temp ;
		if((n & 1) == 1){
			temp = temp * a;
		}
		return temp;
}

     代码主要逻辑在这里:

 //利用递归方法,递归i-1次计算
		int temp = power(a, n >> 1);
		temp = temp * temp ;
		if((n & 1) == 1){
			temp = temp * a;
		}
		return temp;

      假设temp = power(a,n>>1)是已经把第j位计算出来了(最开始计算的是第1位的结果),然后下边的代码

temp = temp * temp ;
		if((n & 1) == 1){
			temp = temp * a;
		}
		return temp;

 是计算第j+1位的结果(最高位是第一位)。if((n & 1) == 1)  这个判断是判断P(n)是否是0。如n=2, 二进制表示为10,那么递归的返回条件里,匹配到这个条件:

if (n == 1) {

			return a ;

		}

 即temp = power(a,n>>1)这行的第一个返回结果是a,那么在下面

temp = temp * temp ;
		if((n & 1) == 1){
			temp = temp * a;
		}
		return temp;

 这段代码,是计算10的第二位,即0这位,首先temp = a,那么temp = temp * temp 结果也是a*a,n&1 =0;所以temp = temp * a 不执行;  最终结果是a*a,即n=2的时候,返回结果是a*a。当n更大的时候,同理。

        下面是lintcode的140题的代码:

public int fastPower(int a, int b, int n) {
		// write your code here
		if (n == 0) {
			return 1 % b;
		}
		if (n == 1) {
			return a % b;
		}
		long temp = fastPower(a, b, n >> 1);
		temp = temp * temp % b;
		if((n & 0x1) == 1){
			temp = temp * a % b;
		}
		return (int)temp;
	}

 需要注意的是这个:long temp = fastPower(a, b, n >> 1); 我刚开始用的是int,结果出错了。。 因为fastPower(a, b, n >> 1);的返回结果可能会超过int的限度,所以我后期改成了long,也算一个小bug。。。

 

猜你喜欢

转载自709002341.iteye.com/blog/2269919