Pow(x, n) 图解题解
这道题到底在问什么
- 输入
- x = 2, n = 11
- 输出
- 2048(即 2^11)
最优解:一步一步想明白
- 3记住两条线:base 每步自乘平方升档(x,x²,x⁴,x⁸…);result 只在「当前二进制位是 1」时把 base 乘进去。
- 4先把 n=11 写成二进制 1011。下面把它低位在左摆开,指针 i 从最低位扫到最高位。result 起步 1,base 起步 x=2。
- 5二进制第 k 位的权重是 2^k。11 = 1+2+8,所以 2^11 只需把这几档(x 的 2^k 次方)乘起来。
- 6一切就绪:result=1、base=x=2,指针 i 落在最低位(第 0 位)。下面开始逐位处理。
- 7指针 i 走到第 0 位,这一位是 1。是 1,说明 x 的这一档(base)要算进答案。
- 8这一位是 1:把当前档 base=2 乘进结果,result 从 1 变成 2。
- 9不管这一位是几,扫完都把 base 自乘平方:base 从 2 升到 4,准备给更高一位用。
- 10第 0 位处理完毕(标灰),指针 i 右移一格去看第 1 位。
- 11指针 i 走到第 1 位,这一位是 1。是 1,说明 x 的这一档(base)要算进答案。
- 12这一位是 1:把当前档 base=4 乘进结果,result 从 2 变成 8。
- 13不管这一位是几,扫完都把 base 自乘平方:base 从 4 升到 16,准备给更高一位用。
- 14第 1 位处理完毕(标灰),指针 i 右移一格去看第 2 位。
- 15指针 i 走到第 2 位,这一位是 0。是 0,说明这一档跳过,result 暂时不动。
- 16这一位是 0:什么都不乘,result 原样保留 8(标红的就是这个被跳过的 0)。
- 17不管这一位是几,扫完都把 base 自乘平方:base 从 16 升到 256,准备给更高一位用。
- 18第 2 位处理完毕(标灰),指针 i 右移一格去看第 3 位。
- 19指针 i 走到第 3 位,这一位是 1。是 1,说明 x 的这一档(base)要算进答案。
- 20这一位是 1:把当前档 base=256 乘进结果,result 从 8 变成 2048。
- 21不管这一位是几,扫完都把 base 自乘平方:base 从 256 升到 65536,准备给更高一位用。
- 22第 3 位是最高位,处理完它,整个二进制就扫完了。
- 23四位全部扫完。所有「位是 1」的档(高亮处)都乘进了 result,最终 2^11 = 2048,这就是答案。
⚠️ 容易写错的地方
✗ 错:n 为负时直接当正数算
✓ 对:先 x = 1/x、n = -n,再按正指数算
x^(-k) = 1 / x^k;忘了取倒数会把负指数算成正指数,结果完全错
✗ 错:用 int 存 n 后对 INT_MIN 取负
✓ 对:先把 n 转成 long 再取负
-INT_MIN 超出 int 范围会溢出;C++/Java 必须先扩成 long 才能安全 -n
✗ 错:result 初值设成 0
✓ 对:result 初值必须是 1
乘法的单位元是 1;从 0 起步会让任何 x^n 都被乘成 0
完整代码(Python / C++ / Java)
Python
def myPow(x, n):
if n < 0: # 负指数:取倒数、指数变正
x, n = 1 / x, -n
result = 1.0
base = x
while n > 0:
if n & 1: # 当前最低位是 1
result *= base # 把这一档乘进答案
base *= base # 升到下一档 x→x²→x⁴…
n >>= 1 # 右移,看下一位
return resultC++
double myPow(double x, int n){
long long m = n; // 防 -INT_MIN 取负溢出
if (m < 0) { x = 1 / x; m = -m; }
double result = 1.0, base = x;
while (m > 0) {
if (m & 1) result *= base;
base *= base;
m >>= 1;
}
return result;
}Java
public double myPow(double x, int n) {
long m = n; // 防 -INT_MIN 取负溢出
if (m < 0) { x = 1 / x; m = -m; }
double result = 1.0, base = x;
while (m > 0) {
if ((m & 1) == 1) result *= base;
base *= base;
m >>= 1;
}
return result;
}复杂度
时间
O(log n)
n 的二进制有约 log₂n 位,每位只做一次乘法,循环 log₂n 趟
空间
O(1)
只用 result 和 base 两个变量,不开额外数组、不递归占栈
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 Pow(x, n) 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
快速幂为什么是 O(log n)?+
n 的二进制只有约 log₂n 位,循环按位走,每位做常数次乘法,所以总乘法次数约为 log₂n,远少于朴素连乘的 n 次。
n = 0 时结果是多少?+
返回 1。循环条件 n>0 直接不进入,result 保持初值 1,符合 x^0 = 1。
递归版和迭代版有什么区别?+
递归版按 x^n = (x^(n/2))² 自顶向下拆,写法直观但占 O(log n) 栈空间;迭代版按二进制位自底向上拼,O(1) 空间,本题演示的就是迭代版。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄把 Pow(x, n) 一步步讲透(全站已上线 905 份讲透,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
把这道题真正拿下
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。