这是我参与更文挑战的第1天,活动详情查看: 更文挑战
leetcode-剑指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 的 二进制串 。
注意:本题与主站 191 题相同:https://leetcode-cn.com/problems/number-of-1-bits/
Related Topics 位运算
👍 131 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:暴力法+位运算
- 通过判断 n & 1 == 1 判断末位是否为1
- 然后无符号右移即可
- 这个的测试用例真的挺奇怪的居然偶尔会TLE
public int hammingWeight(int n) {
int res = 0;
while (n != 0) {
if ((n & 1) == 1) {
res += 1;
}
n >>>= 1;
}
return res;
}
**时间复杂度O(k)**k最大32
思路二:java.Integer库的调用
public int hammingWeight(int n) {
return Integer.bitCount(n);
}
时间复杂度O(logk)k最大32
思路三:位运算的奇思妙想
- n &= (n-1) 会将最后位1变成0
- n-1表示把最后一位的1右边全变成1,当前位变为1,然后与n与运算则表示当前位右侧以及当前位都变成0
- 计算次数则为1的个数
public int hammingWeight(int n) {
int res = 0;
while (n != 0) {
n &= n - 1;
res += 1;
}
return res;
}
时间复杂度O(k)-主要优化的是删除了中间为0的运算
思路四:思路一的多种写法
- 虽然我也没看出来啥优化
public int hammingWeight(int n) {
int ret = 0;
for (int i = 0; i < 32; i++) {
if ((n & (1 << i)) != 0) {
ret += 1;
}
}
return ret;
}
时间复杂度O(k),可能是leetcode更信任常量?
思路五:思路一的多种写法
public int hammingWeight(int n) {
int res = 0;
while (n != 0) {
res += (n & 1);
n >>>= 1;
}
return res;
}
时间复杂度O(k)
思路六-logk写法
- 这个是java库的写法
- 手写了一次运算过程
简化后运算过程
public int hammingWeight(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
这种做法没有宫水三叶 题解中的具有通用性
public int hammingWeight(int n) {
n = (n & 0x55555555) + ((n >>> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >>> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >>> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >>> 16) & 0x0000ffff);
return n;
}
时间复杂度O(logk)k最大32
这做法我印象里做过,但是具体忘记了哪道题了后续会补