LeetCode 191. 位1的个数(C++)
前言
- 汉明重量是一串符号中非零符号的个数。因此它等同于同样长度的全零符号串的汉明距离。在最为常见的数据位符号串中,它是 1 的个数。————百度百科
- 题目提示:输入必须是长度为 32 的 二进制串。
LeetCode 191. 位1的个数(C++)
点击链接开始刷题φ(゜▽゜*)♪:LeetCode104.二叉树的最大深度
SWAR 算法 “计算汉明重量”
- 首先看一下四个十六进制数的二进制表示:
-
0x55555555 — 0101 0101 0101 0101 0101 0101 0101 0101,奇数位为 1, 偶数位为 0
-
0x33333333 — 0011 0011 0011 0011 0011 0011 0011 0011,每半个字节后两位是 1
-
0x0F0F0F0F — 0000 1111 0000 1111 0000 1111 0000 1111,每一个字节后四位是 1
-
0x01010101 — 0000 0001 0000 0001 0000 0001 0000 0001,每一个字节最后一位是 1
-
- 第一步:计算出来的值 n 的二进制可以按每 2 个二进制位为一组进行分组,各组的十进制表示的就是该组的 1 的个数;
- 第二步:计算出来的值 n 的二进制可以按每 4 个二进制位为一组进行分组,各组的十进制表示的就是该组的 1 的个数;
- 第三步:计算出来的值 n 的二进制可以按每 8 个二进制位为一组进行分组,各组的十进制表示的就是该组的 1 的个数;
- 第三步计算完后,其实已经分成了 4 组,每组 8 个⼆进制位,只要求出每组上⼆进制表⽰的值,相加的结果就是输入数据的 1 的个数;
- 第四步:n * (0x01010101)计算出 1 的个数并记录在二进制的高八位,>>24语句则通过右移运算,将 1 的个数移到最低八位,最后二进制对应的十进制数就是 1 的个数。
以输入 0011 1000 1000 1101 0100 1010 0100 1011 为例图示
代码
class Solution {
public:
// 计算32位二进制的汉明重量
int hammingWeight(uint32_t n) {
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);
n = (n * (0x01010101) >> 24);
return n;
}
};
- 时间复杂度:O(1)
- 空间复杂度:O(1)