1.题目
剑指 Offer 15. 二进制中1的个数
请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
提示:
输入必须是长度为 32 的 二进制串 。
进阶:
如果多次调用这个函数,你将如何优化你的算法?
2.自我思路及实现
1.逐位判断
利用&运算和无符号位右移>>>运算符
判断 n&1 == 1,是则计数加一
然后将n右移一位
时间:1,三十二次循环
空间:1,
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
for(int i = 0; i < 32; i++)
{
if((n & 1) == 1)
count ++;
n = n >>> 1;
}
return count;
}
}
3.总结思路及实现
上述思路的优化
使用判断n为0来减少循环次数
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
while(n != 0)
{
if((n & 1) == 1)
count ++;
n >>>= 1;
}
return count;
}
}
或者不右移n而是左移1
2. 巧用n&(n - 1)
在二进制表示中,数字 n 中最低位的 1 总是对应 n−1 中的 0 。因此,将 n 和n−1 与运算总是能把 n 中最低位的 1 变成 0 ,并保持其他位不变
减少了判断次数
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
while(n != 0)
{
n &= (n - 1);
count ++;
}
return count;
}
}
3.Integer.bitCount(n)
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
return Integer.bitCount(n);
}
}
4.相关知识
- 无符号位右移>>>
- 将 n 和n−1 与运算总是能把 n 中最低位的 1 变成 0 ,并保持其他位不变