# Count numbers in range [L, R] having K consecutive set bits

Given three positive integers L, R, and K, the task is to find the count of numbers in the range [L, R] having K consecutive set bits in their binary representation.

Examples:

Input: L = 4, R = 15, K = 3
Output:
Explanation:
Numbers whose binary representation contains K(=3) consecutive set bits are:
(7)10 = (111)2
(14)10 = (1110)2
(15)10 = (1111)2
Therefore, the required output is 3.

Input: L = 8, R = 100, K = 3
Output: 27

Naive Approach: The simplest approach to solve this problem to traverse all possible integers in the range [L, R] and for each number, check if binary representation of the number contains K consecutive 1s or not. If found to be true then print the number.

Time Complexity: O((R – L + 1) * 32)
Auxiliary Space: O(1)

Efficient Approach: The problem can be solved using Digit DP. The idea is to count of numbers having K consecutive 1s in the range [1, R] and subtract the count of the numbers having K consecutive 1s in the range [1, L – 1]. Following are the recurrence relations: [Tex]= \sum^{1}_{i=0} cntN1X(len + 1, cntOne + i, KOne | (cntOne == K))            [/Tex]

cntN1X(len, cntOne, KOne): Stores the count of numbers in the range [1, X] with the following constraints:
len = length of binary representation of X
cntOne = Count of consecutive 1s till index len
KOne = Boolean value to check if K consecutive 1s present in X or not.

Follow the steps below to solve the problem:

• Initialize a 4D array dp[len][cntOne][KOne][tight] to compute and store the values of all subproblems of the above recurrence relation.
• Finally, return the value of dp[len][cntOne][KOne][tight].

Below is the implementation of the above approach:

## C++

 // C++ program to implement // the above approach   #include  using namespace std;   // Function to find the count of numbers in // range[1, X] having K consecutive set bits int cntN1X(string str, int len, int K,      int cntOne, int dp,                  bool KOne, bool tight) {     // If length of current number is     // equal to length of string     if (len == str.length()) {                   // If count of consecutive set bits         // in the current string is >= K         return (KOne == 1);     }           // If already computedx     // equal occurred      if (dp[len][cntOne][KOne][tight]                                     != -1) {         return dp[len][cntOne][KOne][tight];     }       // If tight is 1, then element present     // at current index is element present      // in str at current index. Otherwise, 1.     int end = tight ? (str[len] - '0'): 1;           // Stores count of numbers whose     // len th bit is i.     int res = 0;           // Iterate over all possible      // value present at current index.     for(int i = 0; i <= end; i++) {                   // Stores count of consecutive 1s         int temp = (i==1) ? (cntOne + 1): 0;                   // Update res.         res += cntN1X(str, len + 1,         K, temp, dp, (KOne | (temp == K)),                      (tight & (i==end)));     }           return dp[len][cntOne][KOne][tight]                                     = res; }     // Function to find // binary representation of N string convertBinary(int N) {     // Stores binary      // representation of N.     string res;           // Traverse each bit of N.     while(N) {                   // Append current bit         // in res          res.push_back(N % 2 + '0');                   // Update N.         N /= 2;     }           // Append 0 in binary representation     // Of N     while(res.length() < 32) {         res.push_back('0');     }           // Reverse binary representation of N     reverse(res.begin(), res.end());           return res; }   // Function to count numbers in // range[L, R] having K consecutive 1s. int cntN1XL_R(int L, int R, int K) {     // Stores binary representation      // of (L - 1)     string Ls = convertBinary(L - 1);           // Stores binary representation      // of R     string Rs = convertBinary(R);           // Stores values of overlapping     // subproblems     int dp;           // Initalize dp[][][][] array.     memset(dp, -1, sizeof(dp));           // Stores count of numbers from      // [1, L - 1] having K consecutive 1s     int resL = cntN1X(Ls, 0, K, 0,                             dp, 0,1);           // Initalize dp[][][][] array.     memset(dp, -1, sizeof(dp));                 // Stores count of numbers from      // [1, R - 1] having K consecutive 1s     int resR = cntN1X(Rs, 0, K, 0,                             dp, 0, 1);           // Return total counts having K      // consecutive 1s in range[L, R]     return (resR - resL); }   // Driver Code int main() {     int L = 8;     int R = 100;     int K = 3;     cout<

## Java

 // Java program to implement // the above approach import java.util.*;   class GFG{       // Function to find the count of numbers in // range[1, X] having K consecutive set bits public static int cntN1X(String str, int len, int K,                          int cntOne, int dp[][][][],                          int KOne, int tight) {           // If length of current number is     // equal to length of string     if (len == str.length())      {                   // If count of consecutive set bits         // in the current string is >= K         return (KOne == 1) ? 1 : 0;     }       // If already computedx     // equal occurred     if (dp[len][cntOne][KOne][tight] != -1)     {         return dp[len][cntOne][KOne][tight];     }       // If tight is 1, then element present     // at current index is element present     // in str at current index. Otherwise, 1.     int end = (tight == 1) ?                (str.charAt(len) - '0') : 1;       // Stores count of numbers whose     // len th bit is i.     int res = 0;       // Iterate over all possible     // value present at current index.     for(int i = 0; i <= end; i++)      {                   // Stores count of consecutive 1s         int temp = (i == 1) ? (cntOne + 1) : 0;           // Update res.         res += cntN1X(str, len + 1, K, temp, dp,                      (int)(KOne | ((temp == K) ? 1 : 0)),                      (int)(tight & ((i == end) ? 1 : 0)));     }     return dp[len][cntOne][KOne][tight] = res; }   // Function to count numbers in // range[L, R] having K consecutive 1s. public static int cntN1XL_R(int L, int R, int K) {           // Stores binary representation     // of (L - 1)     String Ls = Integer.toBinaryString(L - 1);       // Stores binary representation     // of R     String Rs = Integer.toBinaryString(R);       // Stores values of overlapping     // subproblems     int dp[][][][] = new int;       // Initalize dp[][][][] array.     for(int i[][][] : dp)         for(int j[][] : i)             for(int k[] : j)                 Arrays.fill(k, -1);       // Stores count of numbers from     // [1, L - 1] having K consecutive 1s     int resL = cntN1X(Ls, 0, K, 0, dp, 0, 1);       // Initalize dp[][][][] array.     for(int i[][][] : dp)         for(int j[][] : i)             for(int k[] : j)                 Arrays.fill(k, -1);       // Stores count of numbers from     // [1, R - 1] having K consecutive 1s     int resR = cntN1X(Rs, 0, K, 0, dp, 0, 1);       // Return total counts having K     // consecutive 1s in range[L, R]     return (resR - resL); }   // Driver Code public static void main(String args[]) {     int L = 8;     int R = 100;     int K = 3;           System.out.println(cntN1XL_R(L, R, K)); } }   // This code is contributed by hemanth gadarla

## C#

 // C# program to implement // the above approach using System;   class GFG{       // Function to find the count of numbers in // range[1, X] having K consecutive set bits public static int cntN1X(String str, int len, int K,                          int cntOne, int [,,,]dp,                          int KOne, int tight) {           // If length of current number is     // equal to length of string     if (len == str.Length)      {                   // If count of consecutive set bits         // in the current string is >= K         return (KOne == 1) ? 1 : 0;     }           // If already computedx     // equal occurred     if (dp[len, cntOne, KOne, tight] != -1)     {         return dp[len, cntOne, KOne, tight];     }           // If tight is 1, then element present     // at current index is element present     // in str at current index. Otherwise, 1.     int end = (tight == 1) ?                (str[len] - '0') : 1;       // Stores count of numbers whose     // len th bit is i.     int res = 0;       // Iterate over all possible     // value present at current index.     for(int i = 0; i <= end; i++)      {                   // Stores count of consecutive 1s         int temp = (i == 1) ? (cntOne + 1) : 0;           // Update res.         res += cntN1X(str, len + 1, K, temp, dp,                      (int)(KOne | ((temp == K) ? 1 : 0)),                      (int)(tight & ((i == end) ? 1 : 0)));     }     return dp[len, cntOne, KOne, tight] = res; }   // Function to count numbers in // range[L, R] having K consecutive 1s. public static int cntN1XL_R(int L, int R, int K) {           // Stores binary representation     // of (L - 1)     String Ls = Convert.ToString(L - 1, 2);       // Stores binary representation     // of R     String Rs = Convert.ToString(R, 2);       // Stores values of overlapping     // subproblems     int [,,,]dp = new int[ 32, 32, 2, 2 ];       // Initalize [,]dp[,] array.     for(int i = 0; i < 32; i++)         for(int j = 0; j < 32; j++)             for(int k = 0; k < 2; k++)                 for(int l = 0; l < 2; l++)                     dp[i, j, k, l] = -1;                           // Stores count of numbers from     // [1, L - 1] having K consecutive 1s     int resL = cntN1X(Ls, 0, K, 0, dp, 0, 1);           // Initalize [,]dp[,] array.     for(int i = 0; i < 32; i++)         for(int j = 0; j < 32; j++)             for(int k = 0; k < 2; k++)                 for(int l = 0; l < 2; l++)                     dp[i, j, k, l] = -1;                           // Stores count of numbers from     // [1, R - 1] having K consecutive 1s     int resR = cntN1X(Rs, 0, K, 0, dp, 0, 1);           // Return total counts having K     // consecutive 1s in range[L, R]     return (resR - resL); }   // Driver Code public static void Main(String []args) {     int L = 8;     int R = 100;     int K = 3;           Console.WriteLine(cntN1XL_R(L, R, K)); } }   // This code is contributed by gauravrajput1

Output

27

`

Time complexity: O(322 * 23)
Auxiliary Space: O(322 * 22)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.