leetcode 50. Pow(x, n)

一 题目

Implement pow(xn), which calculates x raised to the power n (xn).

Example 1:

Input: 2.00000, 10
Output: 1024.00000

Example 2:

Input: 2.10000, 3
Output: 9.26100

Example 3:

Input: 2.00000, -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25

Note:

  • -100.0 < x < 100.0
  • n is a 32-bit signed integer, within the range [−231, 231 − 1]

Accepted 361,215  Submissions 1,263,581

二 分析

medium 级别,求数学的N方运算实现方式。

2.1 直接用乘法实现。

public double myPow(double x, int n) {
        double res =1;
		if(n==0||x ==1){
			return 1.0;
		}
        if(x==-1){
            return n%2==0?1:-1;
        }
		if( (Math.abs(x)<0.001&& n>1) || Math.abs(x)>1&& n<-100 ){
			return 0;
		}
		for(int i=1;i<=Math.abs( n);i++){
			res *= x;
		}
		if(n<0){
			res = 1/res;
		}		
		return res;
    }

Runtime: 14 ms, faster than 5.03% of Java online submissions for Pow(x, n).

Memory Usage: 35.4 MB, less than 5.88% of Java online submissions for Pow(x, n).

当然,上面这个不算是正式的解法,不然一点技术含量都没有了。

怎么处理指数式增长呢?没想出来,我开始想移位。不行。。后来看了grandyang大神的文章.

快速幂等法

上面求幂算法之所以时间复杂度非常高(为O(指数n)),就是因为当指数n非常大的时候,需要执行的循环操作次数也非常大。所以我们快速幂算法的核心思想就是每一步都把指数分成两半,而相应的底数做平方运算使用二分或者折半计算,每次把n缩小一半,这样n最终会缩小到0,任何数的0次方都为1,这时候我们再往回乘,如果此时n是偶数,直接把上次递归得到的值算个平方返回即可,如果是奇数,则还需要乘上个x的值。举个例子:2^1000=(2*2)^500,底数只是做了一个操作,遍历次数就少一半。确实利害,尤其是在N很大的时候(不一定实际计算出结果,题目限制了在100以内,否则double表示不了)。

推导下2^10;

    =4^5

    =4^4*4=16^2*4=256^1*4 =1024

具体实现是递归或者直接循环不重要。如果这个指数运算想不到,那就卡住了。

代码很简洁,甚至不用做上面那么多的判断。简直是跪了。

 public double myPow(double x, int n) {
         double res = 1.0;

        for (int i = n; i !=0; i/=2) {

            if (i%2 != 0){
                res *= x;
            }
             x *= x;
        }

        return n <0 == true ? 1/res : res;

    }

Runtime: 0 ms, faster than 100.00% of Java online submissions for Pow(x, n).

Memory Usage: 33.5 MB, less than 5.88% of Java online submissions for Pow(x, n).

网上还有位操作的实现,在本题区别不大。

其中判断奇偶可以使用&1截取最后一位代替%2.

除以2可以右移1位>>1。

不是重点,重点是快速幂的实现。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值