Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array.
Example:
For num = 5
you should return [0,1,1,2,1,2]
.
Follow up:
- It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
- Space complexity should be O(n).
- Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.
Credits:
Special thanks to @ syedee for adding this problem and creating all test cases.
Given a non-negative integer num. For each number i in the range 0 ≤ i ≤ num , count the number of 1s in its binary numbers and return them as an array.
Example:
such as given num = 5
, should return [0,1,1,2,1,2]
.
Advanced:
- It is very easy to give a solution with time complexity O(n * sizeof(integer)). But can you do it with one traversal in linear time O(n)?
- The space complexity of the algorithm is required to be O(n).
- Can you refine the solution further? Do not use any built-in functions (like __builtin_popcount in c++) in c++ or any other language to do this.
Acknowledgments:
Special thanks to @syedee for adding this question and all the test cases.
In this question, first of all, according to the requirements of the title, we do not consider __builtin_popcount in C++ for direct calculation.
To calculate the number of 1's in its binary number, we first write out some non-negative integers and convert them into binary form to discover the pattern.
0 0000 0 1 0001 1 2 0010 1 3 0011 2 4 0100 1 5 0101 2 6 0110 2 7 0111 3 8 1000 1 9 1001 2 10 1010 2 11 1011 3 12 1100 2 13 1101 3 14 1110 3 15 1111 4
According to the written data, we can see two more obvious laws, which leads to two easier methods
Method 1: We can first see that each i value is the value corresponding to i&(i-1) plus 1, for example: the number of 4 is the number of values of 4&3 plus 1. Regarding the AND (&) operation, You can find relevant information online, the code is as follows:
1 class Solution { 2 public: 3 vector<int> countBits(int num) { 4 vector<int> res; 5 for(int i=1;i<=num;++i) 6 { 7 res[i]=res[i&(i-1)]+1; 8 } 9 return res; 10 } 11 };
Method 2: We can see that the number of 1s in an odd number is the number of 1s in the number obtained by dividing the number by 2 plus 1. For example: the number of 1s corresponding to 3 is the number of 3/2+1 That is, 1+1=2, the code is as follows:
class Solution { public: vector<int> countBits(int num) { vector<int> res{0}; for (int i = 1; i <= num; ++i) { if (i % 2 == 0) res.push_back(res[i / 2]); else res.push_back(res[i / 2] + 1); } return res; } };