快速幂的两种实现方式

前言

快速幂的迭代和递归实现,练习如何递归分解子问题做到统一操作。

一、Pow(x,n)

在这里插入图片描述

二、快速幂

1、递归

//Pow(x,n)
public class MyPower {
    //暴力解:一个一个的乘肯定太浪费时间
    //问题定义:如何做到快速乘法?
    //方案:x的i次方 * x的j次方 = x的i+j次方
    //递归思想,x的n次方 = x 的 n/2次方 * x 的 n/2次方 * n是否为偶数?y:1
    //Time:O(logN),Space:O(logN)
    public double myPow(double x, int n) {
        long en = n;//用long防止越界,比统一成负数处理方便。

        if (en > 0) return quicklyMul(x, en);
        return 1.0 / quicklyMul(x, -en);//负幂次就是正幂次的倒数。
    }

    private double quicklyMul(double x, long n) {
        if (0 == n) return 1.0;

        double rs = quicklyMul(x, n / 2);
        rs *= rs;

        if (1 == (1 & n)) return rs * x;
        return rs;
    }

}

2、统一负数来考虑边界问题

//不用long防止越界
class MyPower2 {
    public double myPow(double x, int n) {
        boolean isPositive = n > 0;
        if (isPositive) n = -n;//负数表示范围大,统一成负数处理

        double rs = quicklyMul(x, (n / 2) * -1);
        rs *= rs;
        rs *= (1 & n) == 0 ? 1 : x;

        if (isPositive) return rs;//统一负数,防止越界
        return 1.0 / rs;//负幂次就是正幂次的倒数。
    }

    private double quicklyMul(double x, int n) {
        if (0 == n) return 1.0;

        double rs = quicklyMul(x, n / 2);
        rs *= rs;

        if (1 == (1 & n)) return rs * x;
        return rs;
    }

}

3、迭代

//一题多解,采用快速幂 + 迭代
class MyPower3 {
    //x的i次方 * x的j次方 = x的i+j次方
    //将n转化为二进制,每位不为0的二进制数加上不就是n吗,如5 == 0101 == 1 + 4
    //Time:O(logN),Space:O(1)
    public double myPow(double x, int n) {
        long en = n;
        if(n < 0) en = -n;

        double rs = 1,temp = x;
        while (en != 0){
            if((en & 1) == 1) rs *= temp;

            temp *= temp;
            en >>>= 1;
        }
        if(n > 0) return rs;
        return 1.0 / rs;
    }

}

总结

1)快速幂
2)递归分解子问题

参考文献

[1] LeetCode Pow(x,n)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值