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

• Last Updated : 29 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

## Javascript

 

Output

27`

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

My Personal Notes arrow_drop_up