Counting Bits

Difficulty: Easy

You're given a non-negative number n. For every number from 0 up to and including n, count how many 1 bits appear in its binary representation, and return all of those counts together as a list (where position i of the list holds the count for the number i).

Examples

Input: n = 2
Output: [0, 1, 1]

0 is 0b0 (zero 1 bits). 1 is 0b1 (one 1 bit). 2 is 0b10 (one 1 bit).

Input: n = 5
Output: [0, 1, 1, 2, 1, 2]

0=0b0, 1=0b1, 2=0b10, 3=0b11 (two 1 bits), 4=0b100 (one 1 bit), 5=0b101 (two 1 bits).

Constraints

  • 0 <= n <= 10^5

Approach

The direct way is to count the 1 bits of each number from 0 to n completely independently, using the same bit-clearing trick you'd use to count the bits of just one number. That's correct, but it redoes a lot of work, since smaller numbers' answers were already computed earlier and thrown away.

A much cheaper approach builds every answer directly from a smaller, already-computed one. Shifting any number i right by one bit (i >> 1) simply drops its last bit and is exactly equal to Math.floor(i / 2) - a smaller number whose 1-bit count was already found earlier in the same pass. The number of 1 bits in i is then just that smaller number's count, plus 1 more if the bit that got dropped (i & 1) was itself a 1. That turns the whole problem into a single pass building up a table of answers, each one reusing an earlier result instead of recomputing anything from scratch.

Solutions

Brute Force - Count Each Number Independently

For every number from 0 to n, count its 1 bits from scratch, using the 'clear the lowest set bit' trick (or an equivalent bit-by-bit check).

function countBits(n) {
  const result = new Array(n + 1).fill(0);

  for (let i = 0; i <= n; i++) {
    let num = i;
    let count = 0;
    while (num > 0) {
      count += num & 1;
      num = num >>> 1;
    }
    result[i] = count;
  }

  return result;
}

Time: O(n log n) - about O(log i) work for each of the n numbers · Space: O(n), for the output list

Optimal - Build Each Answer From a Smaller One

For each number i, its bit count equals the bit count of i >> 1 (i with its last bit dropped, already computed earlier in the same pass) plus 1 if that dropped bit (i & 1) was itself a 1.

function countBits(n) {
  const result = new Array(n + 1).fill(0);

  for (let i = 1; i <= n; i++) {
    result[i] = result[i >> 1] + (i & 1);
  }

  return result;
}

Time: O(n) · Space: O(n), for the output list