LeetCode 第50题:Pow(x, n)
题目描述
实现 pow(x, n),即计算 x 的整数 n 次幂函数。
难度
中等
题目链接
示例
示例 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-1n是一个整数-10^4 <= x^n <= 10^4
解题思路
快速幂算法
这道题如果使用普通的循环乘法会超时,需要使用快速幂算法来优化。快速幂的核心思想是:将幂次按二进制拆分,只计算需要的部分。
关键点:
- 处理n为负数的情况
- 处理n为最小负数的边界情况
- 使用二进制思想优化计算
- 注意浮点数精度问题
具体步骤:
- 处理特殊情况(n为0、x为1等)
- 将负指数转换为正指数处理
- 使用快速幂算法计算结果
- 返回最终结果
图解思路
算法步骤分析表
| 步骤 | 操作 | x | n | 结果 | 说明 |
|---|---|---|---|---|---|
| 初始 | 开始 | 2 | 10 | 1 | n=1010(二进制) |
| 第1步 | n&1=0 | 4 | 5 | 1 | x=x*x, n=n/2 |
| 第2步 | n&1=1 | 16 | 2 | 4 | result*=x |
| 第3步 | n&1=0 | 256 | 1 | 4 | x=x*x, n=n/2 |
| 第4步 | n&1=1 | 256 | 0 | 1024 | result*=x |
状态/情况分析表
| 情况 | 输入 | 输出 | 说明 |
|---|---|---|---|
| 正指数 | x=2,n=3 | 8 | 标准情况 |
| 负指数 | x=2,n=-2 | 0.25 | 需要取倒数 |
| 零指数 | x=2,n=0 | 1 | 特殊情况 |
代码实现
C# 实现
public class Solution {
public double MyPow(double x, int n) {
// 处理特殊情况
if (n == 0) return 1;
if (x == 1) return 1;
if (x == -1) return n % 2 == 0 ? 1 : -1;
// 处理负指数
if (n == int.MinValue) {
x = 1/x;
return x * MyPow(x, -(n + 1));
}
if (n < 0) {
n = -n;
x = 1/x;
}
// 快速幂计算
double result = 1;
while (n > 0) {
if ((n & 1) == 1) {
result *= x;
}
x *= x;
n >>= 1;
}
return result;
}
}
执行结果
- 执行用时:24 ms
- 内存消耗:26.5 MB
代码亮点
- 🎯 使用快速幂算法优化性能
- 💡 巧妙处理负指数和边界情况
- 🔍 使用位运算提高效率
- 🎨 代码结构清晰,逻辑完整
常见错误分析
- 🚫 没有处理负指数情况
- 🚫 整数最小值的特殊处理错误
- 🚫 浮点数精度处理不当
- 🚫 递归深度过大导致栈溢出
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 暴力循环 | O(n) | O(1) | 简单直观 | 效率低 |
| 快速幂(迭代) | O(logn) | O(1) | 效率高 | 需要位运算 |
| 快速幂(递归) | O(logn) | O(logn) | 代码简洁 | 栈空间消耗 |