算法题:剑指 Offer 16. 数值的整数次方(题目+思路+代码+注释)快速幂解法 时空 O(log2N) O(1) 0ms击败100%、95%用户

在这里插入图片描述

题目

剑指 Offer 16. 数值的整数次方
实现 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
-104 <= xn <= 104

注意:本题与主站 50 题相同:https://leetcode-cn.com/problems/powx-n/

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

思路在这里插入图片描述

在这里插入图片描述
认真看懂这个拆解过程,我觉得类似于因式分解的思想,把一个复杂的拆解成方便运算的,而且由于二进制里有0的存在使得能够产生很多不需要乘的项减少运算。另外由于拆解成了二进制,位数其实是从n位减少到了log2n的,因此我们就每次去位上的数字,是1的话就计算下面这个式子的值在这里插入图片描述
,并成让最终结果乘以这个值即可(bi是n在二进制第i位的值,如果是0的话这个式子就会等于1不需要处理了),另外如果是1,那这个式子其实还是可以复用的,从上面的9你可以发现,后面一项其实就是前面一项乘以x而已,因此我们定义一个变量来存储这个数,减少运算。不懂的话你看看这个代码就明白了,理解之后就会觉得快速幂算法很简单的。

代码

public double myPow(double x, int n) {
        if (x == 0){
            return 0;
        }
        //如果幂是负数就先算正数,最后用1除以即可 x^(-1) = 1/(x^1)
        boolean negative = false;
        if (n < 0){
            negative = true;
            n = -n;
        }
        double ret = 1;
        double xi = x;
        while (n != 0){
            int bit = n & 1;
            //如果bit是0的时候 b(i)*2^(i-1)=0,x^0 = 1,乘以1没有意义,因此不处理
            if ( bit == 1){
                ret *= xi;
            }
            //自己相乘
            xi = xi * xi;
            n = n >>> 1;
        }
        if (negative){
            ret = 1/ret;
        }
        return ret;
    }
posted @ 2021-09-12 10:03  HumorChen99  阅读(5)  评论(0编辑  收藏  举报  来源