191. Number of 1 Bits

Write a function that takes an unsigned integer and return the number of '1' bits it has (also known as the Hamming weight).


Example 1:

Input:00000000000000000000000000001011

Output:3

Explanation: The input binary string00000000000000000000000000001011has a total of three '1' bits.

Example 2:

Input:00000000000000000000000010000000

Output:1

Explanation: The input binary string00000000000000000000000010000000has a total of one '1' bit.

Example 3:

Input:11111111111111111111111111111101

Output:31

Explanation: The input binary string11111111111111111111111111111101has a total of thirty one '1' bits.


Note:

Note that in some languages such as Java, there is no unsigned integer type. In this case, the input will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.

In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 3above the input represents the signed integer -3.


Follow up:

If this function is called many times, how would you optimize it?


① 

class Solution(object):

    def hammingWeight(self, n):

        """

        :type n: int

        :rtype: int

        """

        count = 0

        while n!=0:

            if n%2==1:

                count +=1

            n = n//2

        return count

class Solution(object):

    def hammingWeight(self, n):

        """

        :type n: int

        :rtype: int

        """

        s=str(bin(n))

        return s.count('1')


Approach #1 (Loop and Flip) [Accepted]

** Algorithm**

The solution is straight-forward. We check each of the 3232 bits of the number. If the bit is 11, we add one to the number of 11-bits.

We can check the i^{th}ith bit of a number using a bit mask. We start with a mask m=1m=1, because the binary representation of 11 is,

0000 0000 0000 0000 0000 0000 0000 000100000000000000000000000000000001 Clearly, a logical AND between any number and the mask 11 gives us the least significant bit of this number. To check the next bit, we shift the mask to the left by one.

0000 0000 0000 0000 0000 0000 0000 001000000000000000000000000000000010

And so on.

class Solution(object):

    def hammingWeight(self, n):

        """

        :type n: int

        :rtype: int

        """

        count = 0

        mask = 1 # use bit mask to abstract the '1' for different bits

        for i in range(32): #32bits

            if n & mask !=0:

                count +=1

            mask <<= 1#左移

        return count

Approach #2 (Bit Manipulation Trick) [Accepted]

Algorithm

We can make the previous algorithm simpler and a little faster. Instead of checking every bit of the number, we repeatedly flip the least-significant 11-bit of the number to 0, and add 1 to the sum. As soon as the number becomes 0, we know that it does not have any more 1-bits, and we return the sum.

The key idea here is to realize that for any number n, doing a bit-wise AND of n and n−1flips the least-significant 1-bit in n to 0. Why? Consider the binary representations of n and n−1.

Figure 1. AND-ing nn and n-1n−1 flips the least-significant 11-bit to 0.  

In the binary representation, the least significant 1-bit in n always corresponds to a 0-bit in n - 1. Therefore, anding the two numbers n and n−1 always flips the least significant 1-bit in n to 0, and keeps all other bits the same.

Using this trick, the code becomes very simple.

class Solution(object):

    def hammingWeight(self, n):

        """

        :type n: int

        :rtype: int

        """

        count = 0

        while n!=0:

            count +=1

            n &=(n-1)

        return count


①Hamming weight:

汉明重量是一串符号中非零符号的个数。在最为常见的数据位符号串中,它是1的个数。汉明重量是以理查德·卫斯里·汉明的名字命名的,它在包括信息论、编码理论、密码学等多个领域都有应用。

汉明距离:使用在数据传输差错控制编码里面的,汉明距离是一个概念,它表示两个(相同长度)字对应位不同的数量,我们以d(x,y)表示两个字x,y之间的汉明距离。对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。例如:1011101 与 1001001 之间的汉明距离是 2。

汉明重量等同于同样长度的全零符号串的汉明距离。

② 2's complement notation:

Two's complement notation is a way to encode negative numbers into ordinary binary. 

To represent a negative number using two’s complement notation:

Start with the binary representation of the positive version of the number.

Complement all the bits (turn the ones into zeros and the zeros into ones).

Add one to the result.

For example, the binary notation for the number 9 is 00001001. To represent –9 in two’s complement notation, flip the bits (11110110) and then add 1. The two’s complement for –9 is 11110110 + 1 = 11110111. The binary notation for the number 2 is 00000010. The two’s complement for –2 would be 11111101 + 1 =11111110.

What’s important to remember is that the computer uses one notation for positive-only numbers and a different notation for numbers that can be positive or negative. Both notations allow a byte to take on one of 256 different values. The positives-only scheme allows values ranging from 0 to 255. The two’s complement scheme allows a byte to take on values ranging from –128 to 127. Note that both of these ranges contain exactly 256 values. If the 2 bytes are unsigned(never allowed to hold a negative value), they can hold values ranging from 0 to 65,535. If the 2 bytes are signed(allowed to hold both positive and negative values), they can hold values ranging from –32,768 to 32,767. 

2的补码的一个好处就是,它可以直接进行加减乘除运算,并且运算结果就是正确结果的2's complement。

③the usage of bit mask

④the binary representations of n and n−1: for any number n, doing a bit-wise AND of n and n−1 flips the least-significant 1-bit in n to 0. 

你可能感兴趣的:(191. Number of 1 Bits)