如何判断一个数是不是 3 的幂?(LeetCode 326)
简化版
判断 3 的幂可以不断除以 3:如果 n > 0,并且把所有因子 3 除掉后结果为 1,则是 3 的幂。也可以利用 32 位整数范围内最大的 3 的幂 1162261467,判断它是否能被 n 整除。
详细版
boolean isPowerOfThree(int n) {
if (n <= 0) return false;
while (n % 3 == 0) {
n /= 3;
}
return n == 1;
}
数学写法:
boolean isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
第二种依赖整数范围,适合 32 位有界输入;第一种更通用,也更容易解释。
完整版教学
一、3 的幂有什么结构
3 的幂形如:
1, 3, 9, 27, 81, ...
它的质因数只有 3。如果一个正整数可以不断被 3 整除,最后变成 1,它就是 3 的幂。
二、循环除法为什么正确
对 n = 81:
81 -> 27 -> 9 -> 3 -> 1
对 n = 45:
45 -> 15 -> 5
剩下 5,说明除了 3 以外还有其他因子,所以不是 3 的幂。
| 输入 | 除 3 后结果 | 判断 |
|---|---|---|
27 | 1 | true |
45 | 5 | false |
1 | 1 | true |
0 | 不进入 | false |
易错点:
1是3^0,所以应该返回 true;0和负数不是 3 的幂。
三、为什么先判断正数
幂通常定义在正整数范围内。n <= 0 时不应进入循环:
if (n <= 0) return false;
这不仅符合定义,也避免一些语言里对负数取模带来的理解负担。
四、最大幂整除法
在 32 位有符号整数中,最大的 3 的幂是:
3^19 = 1162261467
3^20 > Integer.MAX_VALUE
如果 n 是 3 的幂,那么它一定是 3^19 的因子。因此:
return n > 0 && 1162261467 % n == 0;
这个方法是 O(1),但依赖固定整数范围。
五、为什么最大幂法只适用于质数底
3 是质数,3^19 的正因子只能是 3^0..3^19。如果底数不是质数,比如 4,4^k 的最大幂因子还可能包含 2 的幂干扰,不能照搬。
3^19 的因子只有 3 的幂
这是最大幂法成立的数学基础。
六、复杂度与面试选择
循环除法复杂度 O(log_3 n),空间 O(1);最大幂整除法是 O(1)。
面试时推荐先写循环版,因为它清晰可靠;如果追问“能不能不用循环”,再补最大幂法。
七、常见误区与追问
- 误区:把 1 判成 false。
1 = 3^0,应返回 true。 - 误区:对负数做除法循环后判断。 题目通常只接受正幂,负数直接 false。
- 误区:最大幂常数背错。 32 位 int 下是
1162261467。 - 追问:为什么最大幂能整除所有 3 的幂? 因为它是最高次 3 的幂,低次幂都是它的因子。
- 追问:这个技巧能用于任意底数吗? 对质数底更直接,合数底要小心额外因子。
- 追问:复杂度是多少? 循环版
O(log n),常数整除版O(1)。
八、加强记忆
3 的幂判断有两套话术:通用版“正数不断除 3,最后看 1”;技巧版“32 位最大 3 的幂能否被 n 整除”。先讲通用版保正确,再讲技巧版加分,顺序别反。