Count numbers in the range [l, r] having only three set bits

Last Updated : 29 Aug, 2026

Given two integers l and r, find the count of numbers x such that:

  • l ≤ x ≤ r
  • The binary representation of x contains exactly 3 set bits.

Return the total count of such numbers in the given range.

Examples:

Input: l = 11, r = 19
Output: 4
Explanation: There are 4 such numbers with 3 set bits in range 11 to 19. 11 -> 1011, 13 -> 1101, 14 -> 1110, 19 -> 10011. So answer for this test case is 4.

Input: l = 25, r = 29
Output: 3
Explanation: There are 3 such numbers with 3 set bits in range 25 to 29. 25 -> 11001, 26 -> 11010, 28 -> 11100. So answer for this test case is 3

Try It Yourself
redirect icon

[Naive Approach] Using Bit Counting – O((r − l + 1) × log n) Time and O(1) Space

The idea is to traverse every number in the range [l, r] and count the number of set bits in its binary representation. If a number contains exactly 3 set bits, it is counted in the final answer.

The set bits are counted by repeatedly checking the last bit using (n & 1) and then right-shifting the number.

  • Traverse all numbers from l to r
  • For each number, count set bits in binary representation and If the count equals 3, increment the result
C++
#include <bits/stdc++.h>
using namespace std;

// count set bits in binary
int countSetBits(int n)
{

    int count = 0;

    while (n)
    {

        // check last bit
        if (n & 1)
        {
            count++;
        }

        // right shift
        n = n >> 1;
    }

    return count;
}

// count numbers having exactly 3 set bits
int solve(int l, int r)
{

    int ans = 0;

    // check every number in range
    for (int i = l; i <= r; i++)
    {

        // count set bits
        int bits = countSetBits(i);

        // if exactly 3 set bits
        if (bits == 3)
        {
            ans++;
        }
    }

    return ans;
}

int main()
{
    int l = 1;
    int r = 20;
    cout << solve(l, r);
    return 0;
}
Java
import java.util.*;

class GFG {

    // count set bits in binary
    static int countSetBits(int n)
    {

        int count = 0;

        while (n > 0) {

            // check last bit
            if ((n & 1) == 1) {
                count++;
            }

            // right shift
            n = n >> 1;
        }

        return count;
    }

    // count numbers having exactly 3 set bits
    public static int solve(int l, int r)
    {

        int ans = 0;

        // check every number in range
        for (int i = l; i <= r; i++) {

            // count set bits
            int bits = countSetBits(i);

            // if exactly 3 set bits
            if (bits == 3) {
                ans++;
            }
        }

        return ans;
    }

    public static void main(String[] args)
    {

        int l = 1;
        int r = 20;

        System.out.println(solve(l, r));
    }
}
Python
# precompute function

# count set bits in binary
def countSetBits(n):

    count = 0

    while n:

        # check last bit
        if n & 1:
            count += 1

        # right shift
        n = n >> 1

    return count

# count numbers having exactly 3 set bits
def solve(l, r):

    ans = 0

    # check every number in range
    for i in range(l, r + 1):

        # count set bits
        bits = countSetBits(i)

        # if exactly 3 set bits
        if bits == 3:
            ans += 1

    return ans


l = 1
r = 20

print(solve(l, r))
C#
using System;

class GFG {

    // count set bits in binary
    private static int countSetBits(int n)
    {

        int count = 0;

        while (n > 0) {

            // check last bit
            if ((n & 1) == 1) {
                count++;
            }

            // right shift
            n = n >> 1;
        }

        return count;
    }

    // count numbers having exactly 3 set bits
    public static int solve(int l, int r)
    {

        int ans = 0;

        // check every number in range
        for (int i = l; i <= r; i++) {

            // count set bits
            int bits = countSetBits(i);

            // if exactly 3 set bits
            if (bits == 3) {
                ans++;
            }
        }

        return ans;
    }

    static void Main()
    {

        int l = 1;
        int r = 20;

        Console.WriteLine(solve(l, r));
    }
}
JavaScript
// count set bits in binary
function countSetBits(n)
{

    let count = 0;

    while (n) {

        // check last bit
        if (n & 1) {
            count++;
        }

        // right shift
        n = n >> 1;
    }

    return count;
}

// count numbers having exactly 3 set bits
function solve(l, r)
{

    let ans = 0;

    // check every number in range
    for (let i = l; i <= r; i++) {

        // count set bits
        let bits = countSetBits(i);

        // if exactly 3 set bits
        if (bits === 3) {
            ans++;
        }
    }

    return ans;
}

let l = 1;
let r = 20;

console.log(solve(l, r));

Output
5

[Efficient Approach] Using Precomputation + Binary Search – O(1) Query Time

A number having exactly 3 set bits can be formed by choosing any 3 distinct bit positions. Since a long long integer has at most 63 usable bit positions, all such numbers can be generated beforehand using three nested loops.

After generating all valid numbers:

  • Sort them
  • Use binary search to count how many lie in the range [l, r]

The count is: upperBound(r)−lowerBound(l)

  • Generate all numbers with exactly 3 set bits using:(1LL<<i)  ∣  (1LL<<j)  ∣  (1LL<<k)(1LL << i)
  • Store all generated numbers in a array and sort the array
  • Use: lowerBound() for first index having value >= l and upperBound() for first index having value > r
  • Their difference gives the required count
C++
#include <bits/stdc++.h>
using namespace std;

vector<long long> nums;

// precompute all numbers
void precompute(vector<long long> &nums)
{

    // choose 3 different bit positions
    for (int i = 0; i < 63; i++)
    {

        for (int j = i + 1; j < 63; j++)
        {

            for (int k = j + 1; k < 63; k++)
            {

                // make number using 3 set bits
                long long val = (1LL << i) | (1LL << j) | (1LL << k);

                nums.push_back(val);
            }
        }
    }

    // sort for binary search
    sort(nums.begin(), nums.end());
}

// count numbers in range [l,r]
int solve(int l, int r)
{
    auto low = lower_bound(nums.begin(), nums.end(), l);
    auto high = upper_bound(nums.begin(), nums.end(), r);
    return (int)(high - low);
}

int main()
{
    vector<long long> nums;
    precompute(nums);
    
    int l = 1;
    int r = 20;
    cout << solve(l, r);

    return 0;
}
Java
import java.util.*;

class GFG{

    //precompute all numbers
    static void precompute(ArrayList<Long> nums){

        //choose 3 different bit positions
        for(int i=0;i<63;i++){

            for(int j=i+1;j<63;j++){

                for(int k=j+1;k<63;k++){

                    //make number using 3 set bits
                    long val=(1L<<i)|(1L<<j)|(1L<<k);

                    nums.add(val);
                }
            }
        }

        //sort for binary search
        Collections.sort(nums);
    }

    //first index having value >= target
    static int lowerBound(ArrayList<Long> nums,long target){

        int low=0;
        int high=nums.size()-1;

        int ans=nums.size();

        while(low<=high){

            int mid=low+(high-low)/2;

            if(nums.get(mid)>=target){

                ans=mid;
                high=mid-1;
            }
            else{

                low=mid+1;
            }
        }

        return ans;
    }

    //first index having value > target
    static int upperBound(ArrayList<Long> nums,long target){

        int low=0;
        int high=nums.size()-1;

        int ans=nums.size();

        while(low<=high){

            int mid=low+(high-low)/2;

            if(nums.get(mid)>target){

                ans=mid;
                high=mid-1;
            }
            else{

                low=mid+1;
            }
        }

        return ans;
    }

    //count numbers in range [l,r]
    static int solve(int l,int r){

        //store all numbers having exactly 3 set bits
        ArrayList<Long> nums=new ArrayList<>();

        //generate all valid numbers
        precompute(nums);

        int left=lowerBound(nums,l);

        int right=upperBound(nums,r);

        return right-left;
    }

    public static void main(String[] args){

        int l=1;
        int r=20;

        System.out.println(solve(l,r));
    }
}
Python
#precompute all numbers
def precompute(nums):

    #choose 3 different bit positions
    for i in range(63):

        for j in range(i+1,63):

            for k in range(j+1,63):

                #make number using 3 set bits
                val=(1<<i)|(1<<j)|(1<<k)

                nums.append(val)

    #sort for binary search
    nums.sort()

#first index having value >= target
def lowerBound(nums,target):

    low=0
    high=len(nums)-1

    ans=len(nums)

    while low<=high:

        mid=low+(high-low)//2

        if nums[mid]>=target:

            ans=mid
            high=mid-1

        else:

            low=mid+1

    return ans

#first index having value > target
def upperBound(nums,target):

    low=0
    high=len(nums)-1

    ans=len(nums)

    while low<=high:

        mid=low+(high-low)//2

        if nums[mid]>target:

            ans=mid
            high=mid-1

        else:

            low=mid+1

    return ans

#count numbers in range [l,r]
def solve(l,r):

    #store all numbers having exactly 3 set bits
    nums=[]

    #generate all valid numbers
    precompute(nums)

    left=lowerBound(nums,l)

    right=upperBound(nums,r)

    return right-left

l=1
r=20

print(solve(l,r))
C#
using System;
using System.Collections.Generic;

class GFG{

    //precompute all numbers
    static void precompute(List<long> nums){

        //choose 3 different bit positions
        for(int i=0;i<63;i++){

            for(int j=i+1;j<63;j++){

                for(int k=j+1;k<63;k++){

                    //make number using 3 set bits
                    long val=(1L<<i)|(1L<<j)|(1L<<k);

                    nums.Add(val);
                }
            }
        }

        //sort for binary search
        nums.Sort();
    }

    //first index having value >= target
    static int lowerBound(List<long> nums,long target){

        int low=0;
        int high=nums.Count-1;

        int ans=nums.Count;

        while(low<=high){

            int mid=low+(high-low)/2;

            if(nums[mid]>=target){

                ans=mid;
                high=mid-1;
            }
            else{

                low=mid+1;
            }
        }

        return ans;
    }

    //first index having value > target
    static int upperBound(List<long> nums,long target){

        int low=0;
        int high=nums.Count-1;

        int ans=nums.Count;

        while(low<=high){

            int mid=low+(high-low)/2;

            if(nums[mid]>target){

                ans=mid;
                high=mid-1;
            }
            else{

                low=mid+1;
            }
        }

        return ans;
    }

    //count numbers in range [l,r]
    static int solve(int l,int r){

        //store all numbers having exactly 3 set bits
        List<long> nums=new List<long>();

        //generate all valid numbers
        precompute(nums);

        int left=lowerBound(nums,l);

        int right=upperBound(nums,r);

        return right-left;
    }

    static void Main(){

        int l=1;
        int r=20;

        Console.WriteLine(solve(l,r));
    }
}
JavaScript
//precompute all numbers
function precompute(nums){

    //choose 3 different bit positions
    for(let i=0;i<63;i++){

        for(let j=i+1;j<63;j++){

            for(let k=j+1;k<63;k++){

                //make number using 3 set bits
                let val=(1n<<BigInt(i))|(1n<<BigInt(j))|(1n<<BigInt(k));

                nums.push(val);
            }
        }
    }

    //sort for binary search
    nums.sort((a,b)=>(a<b?-1:1));
}

//first index having value >= target
function lowerBound(nums,target){

    let low=0;
    let high=nums.length-1;

    let ans=nums.length;

    while(low<=high){

        let mid=Math.floor(low+(high-low)/2);

        if(nums[mid]>=target){

            ans=mid;
            high=mid-1;
        }
        else{

            low=mid+1;
        }
    }

    return ans;
}

//first index having value > target
function upperBound(nums,target){

    let low=0;
    let high=nums.length-1;

    let ans=nums.length;

    while(low<=high){

        let mid=Math.floor(low+(high-low)/2);

        if(nums[mid]>target){

            ans=mid;
            high=mid-1;
        }
        else{

            low=mid+1;
        }
    }

    return ans;
}

//count numbers in range [l,r]
function solve(l,r){

    //store all numbers having exactly 3 set bits
    let nums=[];

    //generate all valid numbers
    precompute(nums);

    let left=lowerBound(nums,BigInt(l));

    let right=upperBound(nums,BigInt(r));

    return right-left;
}

let l=1;
let r=20;

console.log(solve(l,r));

Output
5
Comment