LeetCode 50. Pow(x, n)

LeetCode 50. Pow(x, n) 快速幂

题目描述

实现 pow(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/2^2 = 1/4 = 0.25

提示:

  • -100.0 < x < 100.0
  • -2^31 <= n <= 2^31-1
  • n 是一个 32 位有符号整数
  • 结果的范围是 [-10^4, 10^4]

解题思路

计算 x^n 最直接的方法是循环相乘,但时间复杂度为 O(n),当 n 很大时会超时。本题考察的是 快速幂算法(又称"二分幂"、"二进制指数运算"),能在 O(log n) 时间内完成计算。

快速幂核心思想

将指数 n 用二进制表示,例如 n = 13 的二进制为 1101,则:

复制代码
x^13 = x^(8+4+1) = x^8 * x^4 * x^1

我们可以通过不断将底数平方,并检查当前指数二进制的最低位是否为 1,来决定是否乘入结果。具体步骤如下:

  1. 初始化结果 ans = 1
  2. 当指数 n 不为 0 时循环:
    • 若当前指数的最低位为 1,则将当前的底数乘入结果。
    • 底数自乘(相当于指数右移一位后,底数变为原来的平方)。
    • 指数右移一位。
  3. 循环结束后返回结果。

负指数处理

当指数为负数时,根据公式 x^(-n) = 1 / (x^n),我们可以先取指数的绝对值,并将底数取倒数,然后按正指数计算。

溢出问题

由于 n 的范围包含 -2^31(即 -2147483648),直接取反 -n 会超出 int 范围导致溢出。因此,我们先将 n 转换为 long long 类型,再进行取反操作。


代码实现(C++)

cpp 复制代码
class Solution {
public:
    double myPow(double x, int n) {
        double ans = 1.0;          // 初始化结果
        long long m = n;            // 使用64位整数,防止 n = INT_MIN 时取反溢出
        if (m < 0) {                 // 处理负指数
            m = -m;                  // 指数取绝对值
            x = 1.0 / x;             // 底数取倒数
        }
        while (m) {                   // 快速幂循环
            if (m & 1) {               // 当前二进制位为1,乘入当前底数
                ans *= x;
            }
            x *= x;                    // 底数平方,对应指数二进制位的权重
            m >>= 1;                    // 指数右移一位
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度:O(log n)。每次循环指数右移一位,循环次数为指数二进制位数,即 log₂(n)。
  • 空间复杂度:O(1)。仅使用了常数个变量。

示例运行

x = 2.0, n = 10 为例:

  • m = 10(二进制 1010),ans = 1.0
  • 第一轮:m & 1 = 0,不乘;x = 4.0(2²),m = 5101)。
  • 第二轮:m & 1 = 1ans *= 4.0ans = 4.0x = 16.0(4²),m = 210)。
  • 第三轮:m & 1 = 0,不乘;x = 256.0(16²),m = 11)。
  • 第四轮:m & 1 = 1ans *= 256.0ans = 1024.0x = 65536.0m = 0,结束。
  • 返回 1024.0,正确。

注意事项

  1. 必须使用 long long 存储指数,避免 INT_MIN 取反溢出。
  2. 负指数时先取倒数再计算,结果自然正确。
  3. 底数为 0 或指数为 0 时,代码也能正确处理(循环直接跳过,返回初始值 1.0)。

总结

快速幂是处理幂运算的高效算法,其核心在于将指数二进制分解,通过位运算和平方累乘实现 O(log n) 的时间复杂度。本题是快速幂的经典应用,掌握后可用于解决许多类似问题(如矩阵快速幂、斐波那契数列等)。

相关推荐
️是7825 分钟前
信息奥赛一本通—编程启蒙(3395:练68.3 车牌问题)
数据结构·c++·算法
Liangwei Lin41 分钟前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
计算机安禾43 分钟前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
鼠鼠我(‘-ωก̀ )好困1 小时前
leetGPU
算法
我星期八休息1 小时前
Linux系统编程—基础IO
linux·运维·服务器·c语言·c++·人工智能·算法
池塘的蜗牛1 小时前
A Low-Complexity Method for FFT-based OFDM Sensing
算法
故事和你912 小时前
洛谷-【图论2-1】树5
开发语言·数据结构·c++·算法·动态规划·图论
咖啡里的茶i2 小时前
视觉显著目标的自适应分割与动态网格生成算法研究
人工智能·算法·目标跟踪
paeamecium2 小时前
【PAT甲级真题】- String Subtraction (20)
数据结构·c++·算法·pat考试·pat
YL200404262 小时前
047从前序与中序遍历序列构造二叉树
算法·leetcode