题目描述

✅ 231. 2 的幂

image-20260928235035743

题意分析

判断整数 n 能否写成 2 的某个非负整数次幂。指数可以为 0,所以 1 也符合;零和所有负数都不符合。

返回布尔值,不需要求出指数,也不需要构造小于 n 的所有幂。题目使用固定宽度整数,可以直接利用它的二进制位。

解法:清除最低位的 1

核心思路

[!blue]

2 每乘一次自身,二进制中的那一个 1 就向左移动一位,所以正数是 2 的幂,当且仅当它的二进制恰好有一个 1。问题因此转化为判断是否只有一个置位。

对任意正整数做 n - 1,减法会从最低位的 1 借位:这个 1 变成 0,它右边原来的所有 0 变成 1,更高的位保持不变。

再将 n 与 n - 1 按位与。最低的那个 1 因另一侧为 0 而被清除,它右侧各位因原数为 0 也全部为 0,高位则保持原样。因此 n & (n - 1) 恰好清掉原数最低的一个 1,其他 1 不受影响。

如果结果为 0,说明原来只有这一个 1;如果仍非零,说明还有其他置位。这个推理以正数为前提,所以先检查 n > 0,再做位判断,才能排除零和有符号负数。

解题步骤

  1. 若 n <= 0,返回 false。
  2. 对正数计算 n & (n - 1),清除最低的一个二进制 1。
  3. 结果为 0 就返回 true,否则返回 false。代码用短路与把两步合并成一个表达式。

代码实现

class Solution {
    public boolean isPowerOfTwo(int n) {
        // 先排除非正数,再清掉最低的一;归零说明原数只有一个一。
        return n > 0 && (n & (n - 1)) == 0;
    }
}
func isPowerOfTwo(n int) bool {
    // 先排除非正数,再清掉最低的一;归零说明原数只有一个一。
    return n > 0 && n&(n-1) == 0
}

复杂度分析

  • 时间复杂度:$O(1)$,只执行固定次数的整数运算。
  • 空间复杂度:$O(1)$。

关键点总结

[!green]

  • “正数且恰好一个二进制 1”是二的幂的完整判定条件。
  • 减一产生借位变化,按位与利用这一变化只清除最低置位。
  • 正数检查与位判断缺一不可,1 则自然通过,不需要单独处理指数为零。

易错点总结

[!yellow]

  • 只检查按位与结果,会把同样得到零的 n = 0 放行,必须先排除非正数。
  • 写成 n >= 0 仍然接受了零;正确条件是严格大于零。
  • 把 1 当作不符合,会漏掉 2⁰。
  • 忽略括号容易混淆按位与和比较的运算顺序;Java 应明确先算 n & (n - 1),再与零比较。
  • 将十进制位数或偶数性当作充分条件,只能排除一部分数,无法保证二进制仅有一个 1。

相似题目

题目 难度 关联与区别
342. 4的幂 简单 4的幂首先必须是2的幂,还要要求唯一的1落在偶数位位置。
326. 3 的幂 简单 3的幂没有二进制单一置位特征,不能照搬x&(x-1)判定。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/61142860
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!