LeetCode50 Pow(x, n) & 剑指Offer 16 数值的整数次方

LeetCode50 Pow(x, n) & 剑指Offer 16 数值的整数次方

题目

在这里插入图片描述

解题

几个注意点:

  1. n 可正、可负、可为 0。一个数的 0 次方等于 1,严格来讲,0 的 0 次方是没有意义的,如果要追求统一,可以设置为1;n 为负整数时,结果是 1 x − n {1 \over x^{-n}} xn1
  2. x 可正、可负、可为 0。x 为 0 时,0 的 0 次方是 1,0 的正整数次方是 0,0 的负整数次方结果是 Inf,可以使用 1 0 − n 1 \over 0^{-n} 0n1 得到
  3. − 2 31 < = n < = 2 31 − 1 , − 2 31 -2^{31} <= n <= 2^{31}-1,-2^{31} 231<=n<=2311231 转换成正整数时,有些语言会产生越界,要使用 长整型的变量 来存储。因为 JS 是一个弱类型的语言,不会产生越界问题,故代码中没有做处理
  4. 如果使用位运算来完成除 2 的操作,因为 m 的最大取值会是 2 31 2^{31} 231 − 2 31 < = n < = 2 31 − 1 -2^{31} <= n <= 2^{31}-1 231<=n<=2311),所以一定要用 无符号的移位(JS 中是 >>>,不然第 32 位的 1 会让 m 变成负数)。

解题一:快速幂 + 递归

在这里插入图片描述
quickMul 中的基础条件是 if (m === 0) return 1; 可以解决 n = 0 的情况;x = 0 并且 n 不等于 0 (n = 0 的情况基础条件已经处理完毕)时,一定会递归计算 x 1 x^1 x1,结果是 0,所以 x = 0 也可以正常处理。

代码使用位运算来完成除 2 的操作,因为 m 的最大取值会是 2 31 2^{31} 231 − 2 31 < = n < = 2 31 − 1 -2^{31} <= n <= 2^{31}-1 231<=n<=2311),所以一定要用>>>无符号的移位,不然第 32 位的 1 会让 m 变成负数)。

// javascript
var myPow = function(x, n) {
    return n >= 0 ? quickMul(x, n) : 1 / quickMul(x, -n);
};

const quickMul = (x, m) => {
    if (m === 0) return 1;
    // 无符号的移位!!!
    const y = quickMul(x, m >>> 1);
    let res = y * y;
    if ((m & 1) === 1) {
        res *= x;
    }
    return res;
};

在这里插入图片描述

解题二:快速幂 + 迭代

在这里插入图片描述
7 = 0 b 111 , a 7 = a 4 ∗ a 2 ∗ a 1 7 = 0b111,a^7 = a^4 * a^2 * a^1 7=0b111a7=a4a2a1
n = 0 时进不了 while 循环,ans 为初始值 1,返回值是 1;x = 0 且 n 不为 0 的情况下 x_contribute 永远为 0,循环结束后 ans 为 0,符合预期。

// javascript
const myPow = (x, n) => {
    let m = n >= 0 ? n : -n;
    // 贡献的初始值为 x
    let x_contribute = x;
    let ans = 1;
    // 在对 m 进行二进制拆分的同时计算答案
    while (m > 0) {
        if ((m & 1) == 1) {
            // 如果 m 二进制表示的最低位为 1,那么需要计入贡献
            ans *= x_contribute;
        }
        // 将贡献不断地平方
        x_contribute *= x_contribute;
        // 舍弃 m 二进制表示的最低位,这样我们每次只要判断最低位即可
        m >>>= 1;
    }
    return n >= 0 ? ans : 1.0 / ans;
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值