You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

利用位运算O(1)时间判断一个数是否为2的幂

利用位运算O(1)时间判断一个数是否为2的幂

你问到点子上了!这个位运算技巧可是判断2的幂的经典操作,完美契合你要的O(1)时间复杂度要求,原理完全就是你提到的n和n-1的位关系。

核心逻辑拆解

咱们把你说的两个关键点结合起来看:

  • 2的正整数幂的二进制表示只有1位是1,比如2是10、4是100、8是1000
  • 当你对这个数减1时,原来那个唯一的1会变成0,它后面的所有低位都会变成1,比如8-1=7是0111,4-1=3是0011

这时候把n和n-1做按位与运算(&,结果会出现两种情况:

  • 如果n是2的幂:原数唯一的1位在n-1里是0,后面的低位都是1,两者按位与后每一位都是0,最终结果为0
  • 如果n不是2的幂:二进制至少有两个1,减1只会翻转最右边的1及后面的位,左边还有其他1存在,按位与后这些位会保留1,结果肯定不为0

必须注意的边界判断

这里一定要加一个前置条件:n必须是正整数。原因很简单:

  • n=0时,0-1=-1(二进制补码全1),0 & -1结果是0,但0显然不是2的幂;
  • 负数的二进制是补码形式,不可能符合“只有一个1”的特征,所以直接排除。

代码示例(多语言版)

这个逻辑在所有支持位运算的语言里都通用,举几个常用的实现:

  • Java/C++:
public static boolean isPowerOfTwo(int n) {
    return n > 0 && (n & (n - 1)) == 0;
}
  • Python:
def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0
  • Go:
func isPowerOfTwo(n int) bool {
    return n > 0 && (n & (n - 1)) == 0
}

实际测试验证

拿几个数试一下就更直观了:

  • 测试n=8:8 & 7 = 1000 & 0111 = 0000 → 返回True;
  • 测试n=6(二进制110):6 & 5 = 110 & 101 = 100(即4)≠0 → 返回False;
  • 测试n=1:1 & 0 = 0,且1>0 → 返回True(1是2^0,属于2的幂范畴)。

我平时写代码处理内存对齐、分治算法边界判断的时候经常用这个技巧,纯硬件级别的位运算完全没有循环或浮点运算的开销,速度拉满,比循环除2、用对数判断靠谱多了!

火山引擎 最新活动