目录
刷题日期:18:5215 星期三2021年3月24日
个人刷题记录,代码收集,来源皆为leetcode
经过多方讨论和请教,现在打算往Java方向发力
主要答题语言为Java
题目:
剑指 Offer 15. 二进制中1的个数
难度简单98
请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
提示:
- 输入必须是长度为
32
的 二进制串 。
题目分析
根据提示,输入长度为32位的二进制串,看题目里输入的是int型
最简单的方法肯定是直接转换成char类型一个一个数。
这道题涉及到位运算,可能在程序中也需要一些位运算的符号。
与、或、异或、左右移
初始解答:
直接判断最右边然后位移
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int sum = 0;
while(n > 0) {
if (n & 1) {
sum += 1;
n = n >> 1;
}
}
return sum;
}
}
if语句后面报错了,不知道为啥,java也支持位运算
参考了方法一,发现while循环的条件和if 的条件都不对,因为n不是布尔值,所以不能直接拿来当判断条件。
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int sum = 0;
while(n != 0) {
if ((n & 1) == 1) {
sum += 1;
n = n >>> 1;
}
}
return sum;
}
}
修改发现老是超出时间限制,继续修改if中的位移操作。
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int sum = 0;
while(n != 0) {
if ((n & 1) == 1) {
sum += 1;
}
n = n >>> 1;
}
return sum;
}
}
把唯一操作移出就好了,这样按照题目的输入,位移操作被执行了32次,不管是0还是1都会判断然后位移。
这里需要注意,位移操作>>>和>>的区别,前者按位右移补零操作符,具体区别附在了最后面。
执行结果:通过
显示详情
执行用时:1 ms, 在所有 Java 提交中击败了96.85%的用户
内存消耗:35.6 MB, 在所有 Java 提交中击败了9.17%的用户
根据书里“能给面试官带来惊喜的解法”,把一个整数减去1,再与原数做与运算,会把该整数最右边的1变成0,依此进行尝试:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int sum = 0;
while(n != 0) {
n = (n-1) & n;
sum ++;
}
return sum;
}
}
没有问题,就是需要记住性质。
执行结果: 通过
显示详情
执行用时:1 ms, 在所有 Java 提交中击败了96.85%的用户
内存消耗:35.6 MB, 在所有 Java 提交中击败了17.13%的用户
学习他人:
方法一:
炉石鲍勃L1 (编辑过)2021-02-28
无符号右移就可以了
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while(n != 0){
if((n&1) == 1){
res++;
}
n = n>>>1;
}
return res;
}
}
方法二
java.lang包的Integer类的bitCount()方法以整数值的二进制补码表示形式返回one-bits的数量计数。有时将此功能称为人口计数。
用法:
public static int bitCount(int n)
参数:
n: the value whose bits are to be counted
返回:
This method returns the count of the number of one-bits in the two's complement
binary representation of an int value.
月亮很亮L1 2020-02-25
java居然有这个方法
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
return Integer.bitCount(n);
}
}
方法三:
Joker 2020-07-03
python一行
return bin(n).count('1')
Java位运算
下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
总结
以上就是本题的内容和学习过程了,这道题比较简单,理解位运算的思路即可,没啥太多好说的。
欢迎讨论,共同进步。