Advertisement

Counting Bits - LeetCode 338 Solution

Counting Bits - Complete Solution Guide

Counting Bits is LeetCode problem 338, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

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 <= 10 5 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) a

Detailed Explanation

The problem asks you to create an array where each index `i` (from 0 to `n`) contains the count of 1s in the binary representation of `i`. For example, if `n` is 5, the binary representations are: 0 (0), 1 (1), 10 (1), 11 (2), 100 (1), 101 (2). Therefore, the output array should be `[0, 1, 1, 2, 1, 2]`. The challenge emphasizes achieving a linear time complexity O(n) and avoiding built-in functions that directly count set bits.

Solution Approach

The provided solutions employ dynamic programming. They create an array `ans` of size `n+1` initialized with zeros. The algorithm iterates from 1 to `n`, calculating the number of 1s in the binary representation of each number `i`. It cleverly leverages the observation that the number of 1s in `i` is either the same as in `i/2` (if `i` is even) or one more than in `i/2` (if `i` is odd). This is efficiently determined using bitwise operations.

Step-by-Step Algorithm

  1. Step 1: Initialize an array `ans` of size `n+1` with all elements set to 0. `ans[i]` will store the number of 1s in the binary representation of `i`.
  2. Step 2: Iterate from `i = 1` to `n`. For each `i`, calculate `ans[i]` using the formula `ans[i] = ans[i >> 1] + (i & 1)`. `i >> 1` performs a right bit shift (integer division by 2), and `i & 1` checks if `i` is odd (LSB is 1).
  3. Step 3: Return the `ans` array.

Key Insights

  • Insight 1: Recognizing the pattern that the number of 1s in `i` is related to the number of 1s in `i/2` (integer division).
  • Insight 2: Utilizing dynamic programming to store and reuse previously computed results. This avoids redundant calculations.
  • Insight 3: Understanding that the least significant bit (LSB) can be efficiently extracted using the bitwise AND operator (`& 1`). The right bit shift (`>> 1`) effectively divides by 2 while discarding the LSB.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(n)

Topics

This problem involves: Dynamic Programming, Bit Manipulation.

Companies

Asked at: Nvidia.