Solution Three kinds:
Sln 1. Stupid way to shift. The complexity of time is too high, basically is O (n * sizesof (int)).
Sln 2. With a small tip, the even number is two, and the other multiplier is shifted to the left by 1bit, and an odd number is added 1 to the previous gain.
Sln 3. Hamming Weight;
pros and Cons:
Sln 1 is not considered, the complexity is too high. In contrast, the SLN 2 is simpler than the SLN 3, but it is not particularly useful to just brush an algorithm question, but also to consider the actual application scenario. If we use SLN 2, a large lookup table is required if you want to randomly take the number of binary 1. The SLN 3 is always available.
implementation:
SLN2:
std::vector<intint num) { std::vector<int01 } ; for int 2; I <= num; i++ ) { 11 )); } return Bit_count;}
SLN3:
Do it directly with Hamming Weight, pictured from Wikipedia.
//types and constants used in the functions belowtypedef unsigned __INT64 UInt64; //assume this gives 64-bitsConstUInt64 M1 =0x5555555555555555;//binary:0101 ...ConstUInt64 m2 =0x3333333333333333;//binary:00110011 .ConstUInt64 M4 =0x0f0f0f0f0f0f0f0f;//binary:4 Zeros, 4 ones ...ConstUInt64 m8 =0x00ff00ff00ff00ff;//binary:8 Zeros, 8 ones ...ConstUInt64 M16 =0x0000ffff0000ffff;//binary:16 zeros, ones ...ConstUInt64 M32 =0x00000000ffffffff;//binary:32 zeros, ones ...ConstUInt64 HFF =0xffffffffffffffff;//Binary:all onesConstUInt64 h01 =0x0101010101010101;//The sum of the 0,1,2,3 to the power of ...//This was a naive implementation, shown for comparison,//Understanding the better functions.//It uses arithmetic operations (shift, add, and).intpopcount_1 (UInt64 x) {x= (X & M1) + ((x >>1) & M1);//put count of each 2 bits into those 2 bitsx = (x & m2) + ((x >>2) & m2);//put count of each 4 bits into those 4 bitsx = (x & M4) + ((x >>4) & M4);//put count of each 8 bits into those 8 bitsx = (x & M8) + ((x >>8) & M8);//put Count of each of the bits into thosex = (x & M16) + ((x >> -) & M16);//put Count of each of the bits into thosex = (x & M32) + ((x >> +) & M32);//put Count of each of the bits into those returnx;}//This uses fewer arithmetic operations than any other known//implementation on machines with slow multiplication.//It uses arithmetic operations.intpopcount_2 (UInt64 x) {x-= (x >>1) & M1;//put count of each 2 bits into those 2 bitsx = (x & m2) + ((x >>2) & m2);//put count of each 4 bits into those 4 bitsx = (x + (x >>4)) & M4;//put count of each 8 bits into those 8 bitsx + = x >>8;//Put count of each of the bits into their lowest 8 bitsx + = x >> -;//Put count of each of the bits into their lowest 8 bitsx + = x >> +;//Put count of each of the bits into their lowest 8 bits returnX &0xFF;}//This uses fewer arithmetic operations than any other known//implementation on machines with fast multiplication.//It uses arithmetic operations, one of the which is a multiply.intpopcount_3 (UInt64 x) {x-= (x >>1) & M1;//put count of each 2 bits into those 2 bitsx = (x & m2) + ((x >>2) & m2);//put count of each 4 bits into those 4 bitsx = (x + (x >>4)) & M4;//put count of each 8 bits into those 8 bits return(x * h01) >> About;//returns left 8 bits of X + (X<<8) + (x<<16) + (x<<24) + ...}
Leetcode 338–counting Bits