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
Table of Content
[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 exactly3set 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
ltor - For each number, count set bits in binary representation and If the count equals
3, increment the result
#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;
}
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));
}
}
# 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))
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));
}
}
// 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
3set bits can be formed by choosing any3distinct bit positions. Since along longinteger has at most63usable 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
3set 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
#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;
}
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));
}
}
#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))
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));
}
}
//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
