Skip to content
Related Articles
Count numbers in range [L, R] having K consecutive set bits
• Last Updated : 03 Jun, 2021

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 bitsint 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 Nstring 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;         // Initialize 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);         // Initialize 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 Codeint main(){    int L = 8;    int R = 100;    int K = 3;    cout<

## Java

 // Java program to implement// the above approachimport java.util.*; class GFG{     // Function to find the count of numbers in// range[1, X] having K consecutive set bitspublic 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;     // Initialize 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);     // Initialize 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 Codepublic 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

## Python3

 # Python3 program to implement# the above approach  # Function to find the count of numbers in# range[1, X] having K consecutive set bitsdef cntN1X(stri, leng, K, cntOne, dp, KOne, tight):     # If length of current number is    # equal to length of string    if (leng == len(stri)):                  # If count of consecutive set bits        # in the current string is >= K        return 1 if (KOne == 1) else 0;              # If already computedx    # equal occurred    if (dp[leng][cntOne][KOne][tight]  != -1):        return dp[leng][cntOne][KOne][tight];          # If tight is 1, then element present    # at current index is element present    # in stri at current index. Otherwise, 1.    end = (ord(stri[leng]) - ord('0')) if tight == 1 else 1;          # Stores count of numbers whose    # leng th bit is i.    res = 0;          # Iterate over all possible    # value present at current index.    for i in range(end + 1):                  # Stores count of consecutive 1s        temp = (cntOne + 1) if (i == 1) else 0;                  # Update res.        res += cntN1X(stri, leng + 1,        K, temp, dp, 1 if(KOne | (temp == K)) else 0,                    1 if(tight & (i == end)) else 0);         dp[leng][cntOne][KOne][tight]= res    return res  # Function to find# binary representation of Ndef convertBinary(N):     # Stores binary    # representation of N.    res=''          # Traverse each bit of N.    while(N != 0):                  # Append current bit        # in res        res += chr((N % 2) + ord('0'));                  # Update N.        N //= 2;             # Append 0 in binary representation    # Of N    while(len(res) < 32):        res += '0';              # Reverse binary representation of N    return res[::-1]; # Function to count numbers in# range[L, R] having K consecutive 1s.def cntN1XL_R(L, R, K):     # Stores binary representation    # of (L - 1)    Ls = str(convertBinary(L - 1));          # Stores binary representation    # of R    Rs = str(convertBinary(R));          # Stores values of overlapping    # subproblems    dp =[[[[-1,-1] for j in range(2)] for k in range(32)] for l in range(32)]          # Stores count of numbers from    # [1, L - 1] having K consecutive 1s    resL = cntN1X(Ls, 0, K, 0, dp, 0,1);              # Initialize dp[][][][] array.    dp = [[[[-1, -1] for j in range(2)] for k in range(32)] for l in range(32)]              # Stores count of numbers from    # [1, R - 1] having K consecutive 1s    resR = cntN1X(Rs, 0, K, 0,                            dp, 0, 1);          # Return total counts having K    # consecutive 1s in range[L, R]    return (resR - resL);  # Driver Codeif __name__=='__main__':         L = 8;    R = 100;    K = 3;    print(cntN1XL_R(L, R, K))     # This code is contributed by rutvik_56

## C#

 // C# program to implement// the above approachusing System; class GFG{     // Function to find the count of numbers in// range[1, X] having K consecutive set bitspublic 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 ];     // Initialize [,]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);         // Initialize [,]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 Codepublic 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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes

My Personal Notes arrow_drop_up