剑指Offer15二进制中1的个数
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. 代码实现
2.1 方法一
Integer.toBinaryString(n);
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
String str = Integer.toBinaryString(n);
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 49){
count++;
}
}
return count;
}
}
2.2 方法二
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
return Integer.toBinaryString(n).replaceAll("0","").length();
}
}
2.3 ☆方法三☆
本题解考察点的体现—位运算,下面是
剑指Offer100页
的内容:
其实二进制的位运算并不是很难掌握,因为位运算总共只有五种运算:
与、或、异或、左移和右移。
与、或和异或运算的规律我们可以用下表总结如下:
左移运算符m<<n表示把m左移n位。
左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。比如:00001010<<2 = 00101000 10001010<<3 = 01010000
右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要稍微复杂一点。
如果数字是一个无符号数值,则用0填补最左边的n位。
如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说如果数字原先是一个正数,则右移之后在最左边补n个0;
如果数字原先是负数,则右移之后在最左边补n个1。
下面是对两个8位有符号数作右移的例子:
00001010>>2 = 00000010 10001010>>3 = 11110001
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
// 用来计数的
int count = 0;
// 只要n不等于0,就一直执行
while(n != 0){
count++;
// 考察点
n = n&(n-1);
}
return count;
}
}
3. 结果分析
方法一执行结果:
- 执行用时:2 ms, 在所有 Java 提交中击败了6.62%的用户
- 内存消耗:35.3 MB, 在所有 Java 提交中击败了87.65%的用户户
方法二执行结果:
- 执行用时:9 ms, 在所有 Java 提交中击败了6.62%的用户
- 内存消耗:36.5 MB, 在所有 Java 提交中击败了5.11%的用户
方法三执行结果:
执行用时:1 ms, 在所有 Java 提交中击败了98.44%的用户
- 内存消耗:35.5 MB, 在所有 Java 提交中击败了68.91%的用户