题意:1的位数
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011
, so the function should return 3.
题意:
写一个功能,输入一个无符号的整数,返回该整数的二进制表示中1的个数。
思路一:
迭代32次该整数,每次将该整数最低位与1相与,得到是否是1,将值累加,并将n右移一位。
代码:C++版:8ms
class Solution { public: int hammingWeight(uint32_t n) { int count = 0; while (n) { if (n&1) { count++; } n = n>>1; } return count; } };
思路二:
递归整数n,通过n & (n - 1)可以将n的二进制中1的个数减少1,而在计数上累加1,完成对1的计数。
代码:C++版:8ms
class Solution { public: int hammingWeight(uint32_t n) { return n==0 ? 0 : 1 + hammingWeight(n & (n - 1)); } };
思路三:转载:https://discuss.leetcode.com/topic/9915/short-code-of-c-o-m-by-time-m-is-the-count-of-1-s-and-another-several-method-of-o-1-time
hamming_weight:对任何32位的无符号整形,都只需要5次移位运算,时间复杂度为常数,所以为O(1).
这里运用了分治的思想,先计算每对相邻的2位中有几个1,再计算每相邻的4位中有几个1,下来8位,16位,32位,因为2^5=32,所以对于32位的机器,5条位运算语句就够了。
比如十六位二进制码:0010 1001 1110 0101
1. (0010 1001 1110 0101 & 1010 1010 1010 1010)>>1 (= 0001 0100 0101 0000)
+
(0010 1001 1110 0101 & 0101 0101 0101 0101) (= 0000 0001 0100 0101)
= 0001 0101 1001 0101
2. (0001 0101 1001 0101 & 1100 1100 1100 1100) >> 2 (= 0000 0001 0010 0001)
+
(0001 0101 1001 0101 & 0011 0011 0011 0011) (= 0001 0001 0001 0001)
= 0001 0010 0011 0010
3. (0001 0010 0011 0010 & 1111 0000 1111 0000)>>4 (= 0000 0001 0000 0011)
+
(0001 0010 0011 0010 & 0000 1111 0000 1111) (= 0000 0010 0000 0010)
= 0000 0011 0000 0101
4. (0000 0011 0000 0101 & 1111 1111 0000 0000) >> 8 (= 0000 0000 0000 0011)
+
(0000 0011 0000 0101 & 0000 0000 1111 1111) ( = 0000 0000 0000 0101)
= 0000 0000 0000 1000
1、比较显式的写法,帮助理解步骤。使用移位、加、与运算符完成
代码:C++版:4ms
class Solution { public: int hammingWeight(uint32_t n) { n = (n & 0x55555555) + (n >> 1 & 0x55555555); // put count of each 2 bits into those 2 bits n = (n & 0x33333333) + (n >> 2 & 0x33333333); // put count of each 4 bits into those 4 bits n = (n & 0x0F0F0F0F) + (n >> 4 & 0x0F0F0F0F); // put count of each 8 bits into those 8 bits n = (n & 0x00FF00FF) + (n >> 8 & 0x00FF00FF); // put count of each 16 bits into those 16 bits n = (n & 0x0000FFFF) + (n >> 16 & 0x0000FFFF); // put count of each 32 bits into those 32 bits return n; } };2、这一种相较于上一种操作步骤更少一点儿。
代码:C++版:8ms
class Solution { public: int hammingWeight(uint32_t n) { n -= (n >> 1) & 0x55555555; //put count of each 2 bits into those 2 bits n = (n & 0x33333333) + (n >> 2 & 0x33333333); //put count of each 4 bits into those 4 bits n = (n + (n >> 4)) & 0x0F0F0F0F; //put count of each 8 bits into those 8 bits n += n >> 8; // put count of each 16 bits into those 8 bits n += n >> 16; // put count of each 32 bits into those 8 bits return n & 0xFF; } };3、相较于以上两种,操作更少。
代码:C++版:4ms
class Solution { public: int hammingWeight(uint32_t n) { n -= (n >> 1) & 0x55555555; // put count of each 2 bits into those 2 bits n = (n & 0x33333333) + (n >> 2 & 0x33333333); // put count of each 4 bits into those 4 bits n = (n + (n >> 4)) & 0x0F0F0F0F; // put count of each 8 bits into those 8 bits return n * 0x01010101 >> 24; // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) } };