[Leetcode] 338. Counting Bits - JavaScript
This algorithm problem is from leetcode.
Problem
Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1โs in the binary representation of i.
Example 1:
Input: n = 2 Output: [0,1,1] Explanation: 0 โ> 0 1 โ> 1 2 โ> 10 Example 2:
Input: n = 5 Output: [0,1,1,2,1,2] Explanation: 0 โ> 0 1 โ> 1 2 โ> 10 3 โ> 11 4 โ> 100 5 โ> 101
Constraints:
0 <= n <= 105
Follow up:
It is very easy to come up with a solution with a runtime of O(n log n). Can you do it in linear time O(n) and possibly in a single pass? Can you do it without using any built-in function (i.e., like __builtin_popcount in C++)?
Submission 1 - Shifting Bits
Runtime 81 ms | Memory 49.4 MB
I used bitwise >>
operator and &
.
Instead of counting number of 1โs in given i
one by one, I could use number of 1โs in previously calculated number that is less than i
and has the common 1โs with given i
.
This picked number is i/2
, which can be calculated by ` iย ยป 1.
Since
i/2 or
iย ยป 1 will have the same number of 1's except the last bit,
I add the last bit (1 or 0) of
i to the number of 1's of
i/2 by doing
i & 1`.
var countBits = function(n) {
const outputArr = [];
outputArr[0] = 0;
for (let i =1; i <= n; i++) {
outputArr[i] = outputArr[i >> 1] + (i & 1);
}
return outputArr;
};
Submission 2
Runtime 66 ms | Memory 48.4 MB This submission was faster than the previous one.
Instead of counting number of 1โs in given i
one by one,
I could use the number of 1โs of the closest pre-calculated number that has the common number of 1โs with i
.
By running i & (i-1)
, I could โfilterโ out the 1โs of the closest number that has the maximum number of common 1โs with i
.
i & (i-1)
could result in i-1
or some other previous number that doesnโt contain 1โs of i-1
not in i
(for example, 1011 & 1100
will result in 1000
. 1000
doesnโt contain 0011
that is in i-1=1011
, but not in i=1100
).
After that, I just need to add i
โs additional 1 bit to the number of 1โs of the closest number.
/**
* @param {number} n
* @return {number[]}
*/
var countBits = function(n) {
const outputArr = [];
outputArr[0] = 0;
for (let i =1; i <= n; i++) {
outputArr[i] = outputArr[i & (i-1)] + 1;
}
return outputArr;
};
Leave a comment