【每日一题】50. Pow(x, n)

本文介绍了如何使用二分快速幂算法优化计算x的n次幂问题,避免了直接模拟乘法带来的时间复杂度过高。通过数组记录关键步骤,实现O(logn)的时间复杂度。
摘要由CSDN通过智能技术生成

50. Pow(x, n) - 力扣(LeetCode)

实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000

示例 2:

输入:x = 2.10000, n = 3
输出:9.26100

示例 3:

输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25

提示:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • n 是一个整数
  • 要么 x 不为零,要么 n > 0 。
  • -104 <= xn <= 104
class Solution {
    public double myPow(double x, int n) {
        if(n == 0) return 1;
        if(x == 1) return 1;     
        long ln = n;
        if(ln < 0) {
            ln = -ln ;
            x = 1.0/x;
        }
        long tmp = ln ;

        ArrayList<Long> arr = new ArrayList();

        while(tmp > 1) {
            if(tmp%2 == 1) {
                tmp/=2;
                arr.add(tmp);
            } else {
                tmp/=2;
            }
        }

        long flag = 1;
        double y = x;

        while(flag < ln) {
            x*=x;
            System.out.println(flag);
            if(arr.contains(flag)) {
                x*=y;
                flag*=2;
                flag += 1;
            } else {
                flag *= 2;
            }
        }


        return x;
    }
}

        今天这道题是一道中等题。

        题目很简单,实现x的n次幂。看完题目,其实最简单的方法就是直接模拟,一个循环一个个乘过去就可以了。但是看看n的数量,2的31次方-1,基本上O(n)的方法是没有办法通过的。应该去寻找更快的方法。这题实际上可以使用二分快速幂!!!

        实际上我们可以观察每一个数,例如10。 每次除2的话,会得到什么?5,2,1。每次二分的话,就可以得到lO(logn)的时间复杂度。但,奇数怎么办?就像10二分完会得到一个5,5实际上是没办法再由一个数来获得的,然而5可以由4+1。从结果10倒推回1的话,可以发现,10次方可以由5次方平方。5次方,可以由2次方平方再*1次方。平方就直接平方就可以了。所以,难点其实只在于什么时候要对前一个数平方完之后要不要乘一个一次方,让其可以得到目标数。

        由于我们是倒着推回去的,最重要的问题是要怎么记录什么时候要相加。如果直接由n/2回去,实际上需要乘一次方的位置不是现在的位置,因为那是在奇数/2次方的时候才要做的事。那倒着推回去,会想到递归!!!让其一直压栈,保存状态,直到从1开始处理。但递归比较难理解,感兴趣的小伙伴可以去看看题解。

        博主这里使用的是记录。其实不一定要递归,只需要记住到底什么时候需要乘一次方就行了。那就用一个数组记录。如果直接创建数组,n的规模太大,最后会出现超出内存限制的错误。

实际上也没必要开那么大的数组,只需要使用arrlist,记录关键位置,之后用一个数,从1开始乘2,看看这个数是否在arrlist里,如果在arrlist里,那么就说明平方完要再乘一次方。如果不再,平方完即可。当然,不要忘记如果在arrlist里,那么这个用来循环的数也要+1,这样才能平衡。至于边界控制,大家可以自己决定。

        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值