相关题目
- 求int型正整数在内存中存储时1的个数(牛客网链接)
- 求int型整数i的二进制形式中1的个数 (剑指 offer)
解题思路
方法一
位运算。我们已知 i i i 是一个 int 型整数,那么它的二进制表达式由若干个 0、1 组合而成。位操作表达式 i & ( i − 1 ) i \& (i-1) i&(i−1) 可以将一个整数的最低位的 1 置为 0,这正是我们需要的。
i & ( i − 1 ) i \& (i-1) i&(i−1) 这个表达式涉及到按位与( & \& &)操作,它对二进制数的每一位进行与操作,当两个相应位都是 1 时,结果才为 1,否则为 0。
该思路的代码实现如下所示:
/**
* @param i 整数 i
* @return res 整数i的二进制形式中1的个数
*/
public int countBits(int i) {
int res = 0;
while (i != 0) {
res++;
i = i & (i - 1);
}
return res;
}
上述代码的时间复杂度是 O ( k ) O(k) O(k) 。因为如果一个整数有 k 位,那么它的二进制形式中可能有 O ( k ) O(k) O(k) 个1,在上述代码的 while 循环中会执行 O ( k ) O(k) O(k) 次。
这个技巧在计算机编程中非常有用,尤其是在处理位操作和位掩码时。例如,它可以用于高效地计算一个整数的二进制表示中 1 的个数,或者判断一个整数是否为 2 的幂。 如果一个整数是 2 的幂,那么 i & ( i − 1 ) i \& (i-1) i&(i−1) 等于 0 ( 注意:这种方法在 i = 0 i=0 i=0 时无效,因为 0 不是 2 的幂)。
方法二
根据 i / 2 i/2 i/2 计算 i i i 的二进制形式中 1 的个数。