Skip to content
Related Articles

Related Articles

Improve Article

Count number of binary strings without consecutive 1’s : Set 2

  • Difficulty Level : Hard
  • Last Updated : 02 Jun, 2021

Given a positive integer N, the task is to count all possible distinct binary strings of length N such that there are no consecutive 1’s.

Examples: 

Input: N = 5 
Output:
Explanation: 
The non-negative integers <= 5 with their corresponding binary representations are: 
0 : 0 
1 : 1 
2 : 10 
3 : 11 
4 : 100 
5 : 101 
Among them, only 3 has two consecutive 1’s. Therefore required count = 5

Input: N = 12 
Output:
 

Dynamic Programming Approach: A dynamic programming approach has already been discussed in this article



Approach: In this article, an approach using the concept of digit-dp is discussed. 

  • Similar to the digit-dp problem, a 3-dimensional table is created here to store the computed values. It is assumed that the N < 231 – 1, and the range of every number is only 2 (Either 0 or 1). Therefore, the dimensions of the table are taken as 32 x 2 x 2.
  • After constructing the table, the given number is converted to a binary string.
  • Then, the number is iterated. For every iteration: 
    1. Check if the previous digit is a 0 or 1.
    2. If it is a 0, then the present number can either be a 0 or 1.
    3. But if the previous number is 1, then the present number has to be 0 because we can’t have two consecutive 1’s in the binary representation.
  • Now, the table is exactly filled like the digit-dp problem.

Below is the implementation of the above approach  

C++




// C++ program to count number of
// binary strings without consecutive 1’s
 
#include <bits/stdc++.h>
using namespace std;
 
// Table to store the solution of
// every sub problem
int memo[32][2][2];
 
// Function to fill the table
/* Here,
   pos: keeps track of current position.
   f1: is the flag to check if current
         number is less than N or not.
   pr: represents the previous digit
*/
int dp(int pos, int fl, int pr, string& bin)
{
    // Base case
    if (pos == bin.length())
        return 1;
 
    // Check if this subproblem
    // has already been solved
    if (memo[pos][fl][pr] != -1)
        return memo[pos][fl][pr];
 
    int val = 0;
 
    // Placing 0 at the current position
    // as it does not violate the condition
    if (bin[pos] == '0')
        val = val + dp(pos + 1, fl, 0, bin);
 
    // Here flag will be 1 for the
    // next recursive call
    else if (bin[pos] == '1')
        val = val + dp(pos + 1, 1, 0, bin);
 
    // Placing 1 at this position only if
    // the previously inserted number is 0
    if (pr == 0) {
 
        // If the number is smaller than N
        if (fl == 1) {
            val += dp(pos + 1, fl, 1, bin);
        }
 
        // If the digit at current position is 1
        else if (bin[pos] == '1') {
            val += dp(pos + 1, fl, 1, bin);
        }
    }
 
    // Storing the solution to this subproblem
    return memo[pos][fl][pr] = val;
}
 
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
int findIntegers(int num)
{
    // Convert N to binary form
    string bin;
 
    // Loop to convert N
    // from Decimal to binary
    while (num > 0) {
        if (num % 2)
            bin += "1";
        else
            bin += "0";
        num /= 2;
    }
    reverse(bin.begin(), bin.end());
 
    // Initialising the table with -1.
    memset(memo, -1, sizeof(memo));
 
    // Calling the function
    return dp(0, 0, 0, bin);
}
 
// Driver code
int main()
{
    int N = 12;
    cout << findIntegers(N);
 
    return 0;
}

Java




// Java program to count number of
// binary Strings without consecutive 1’s
class GFG{
  
// Table to store the solution of
// every sub problem
static int [][][]memo = new int[32][2][2];
  
// Function to fill the table
/* Here,
   pos: keeps track of current position.
   f1: is the flag to check if current
         number is less than N or not.
   pr: represents the previous digit
*/
static int dp(int pos, int fl, int pr, String bin)
{
    // Base case
    if (pos == bin.length())
        return 1;
  
    // Check if this subproblem
    // has already been solved
    if (memo[pos][fl][pr] != -1)
        return memo[pos][fl][pr];
  
    int val = 0;
  
    // Placing 0 at the current position
    // as it does not violate the condition
    if (bin.charAt(pos) == '0')
        val = val + dp(pos + 1, fl, 0, bin);
  
    // Here flag will be 1 for the
    // next recursive call
    else if (bin.charAt(pos) == '1')
        val = val + dp(pos + 1, 1, 0, bin);
  
    // Placing 1 at this position only if
    // the previously inserted number is 0
    if (pr == 0) {
  
        // If the number is smaller than N
        if (fl == 1) {
            val += dp(pos + 1, fl, 1, bin);
        }
  
        // If the digit at current position is 1
        else if (bin.charAt(pos) == '1') {
            val += dp(pos + 1, fl, 1, bin);
        }
    }
  
    // Storing the solution to this subproblem
    return memo[pos][fl][pr] = val;
}
  
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int findIntegers(int num)
{
    // Convert N to binary form
    String bin = "";
  
    // Loop to convert N
    // from Decimal to binary
    while (num > 0) {
        if (num % 2 == 1)
            bin += "1";
        else
            bin += "0";
        num /= 2;
    }
    bin = reverse(bin);
  
    // Initialising the table with -1.
    for(int i = 0; i < 32; i++){
        for(int j = 0; j < 2; j++){
            for(int l = 0; l < 2; l++)
                memo[i][j][l] = -1;
        }
    }
  
    // Calling the function
    return dp(0, 0, 0, bin);
}
static String reverse(String input) {
    char[] a = input.toCharArray();
    int l, r = a.length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.valueOf(a);
}
 
// Driver code
public static void main(String[] args)
{
    int N = 12;
    System.out.print(findIntegers(N));
  
}
}
 
// This code is contributed by sapnasingh4991

Python3




# Python program to count number of
# binary strings without consecutive 1’s
 
 
 
# Table to store the solution of
# every sub problem
memo=[[[-1 for i in range(2)] for j in range(2)] for k in range(32)]
 
# Function to fill the table
''' Here,
pos: keeps track of current position.
f1: is the flag to check if current
        number is less than N or not.
pr: represents the previous digit
'''
def dp(pos,fl,pr,bin):
    # Base case
    if (pos == len(bin)):
        return 1;
 
    # Check if this subproblem
    # has already been solved
    if (memo[pos][fl][pr] != -1):
        return memo[pos][fl][pr];
 
    val = 0
 
    # Placing 0 at the current position
    # as it does not violate the condition
    if (bin[pos] == '0'):
        val = val + dp(pos + 1, fl, 0, bin)
 
    # Here flag will be 1 for the
    # next recursive call
    elif (bin[pos] == '1'):
        val = val + dp(pos + 1, 1, 0, bin)
 
    # Placing 1 at this position only if
    # the previously inserted number is 0
    if (pr == 0):
 
        # If the number is smaller than N
        if (fl == 1):
            val += dp(pos + 1, fl, 1, bin)
 
        # If the digit at current position is 1
        elif (bin[pos] == '1'):
            val += dp(pos + 1, fl, 1, bin)
         
    # Storing the solution to this subproblem
    memo[pos][fl][pr] = val
    return val
 
# Function to find the number of integers
# less than or equal to N with no
# consecutive 1’s in binary representation
def findIntegers(num):
    # Convert N to binary form
    bin=""
 
    # Loop to convert N
    # from Decimal to binary
    while (num > 0):
        if (num % 2):
            bin += "1"
        else:
            bin += "0"
        num //= 2
     
    bin=bin[::-1];
 
     
 
    # Calling the function
    return dp(0, 0, 0, bin)
 
# Driver code
if __name__ == "__main__":
 
    N = 12
    print(findIntegers(N))

C#




// C# program to count number of
// binary Strings without consecutive 1’s
using System;
 
public class GFG{
   
// Table to store the solution of
// every sub problem
static int [,,]memo = new int[32,2,2];
   
// Function to fill the table
/* Here,
   pos: keeps track of current position.
   f1: is the flag to check if current
         number is less than N or not.
   pr: represents the previous digit
*/
static int dp(int pos, int fl, int pr, String bin)
{
    // Base case
    if (pos == bin.Length)
        return 1;
   
    // Check if this subproblem
    // has already been solved
    if (memo[pos,fl,pr] != -1)
        return memo[pos,fl,pr];
   
    int val = 0;
   
    // Placing 0 at the current position
    // as it does not violate the condition
    if (bin[pos] == '0')
        val = val + dp(pos + 1, fl, 0, bin);
   
    // Here flag will be 1 for the
    // next recursive call
    else if (bin[pos] == '1')
        val = val + dp(pos + 1, 1, 0, bin);
   
    // Placing 1 at this position only if
    // the previously inserted number is 0
    if (pr == 0) {
   
        // If the number is smaller than N
        if (fl == 1) {
            val += dp(pos + 1, fl, 1, bin);
        }
   
        // If the digit at current position is 1
        else if (bin[pos] == '1') {
            val += dp(pos + 1, fl, 1, bin);
        }
    }
   
    // Storing the solution to this subproblem
    return memo[pos,fl,pr] = val;
}
   
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int findints(int num)
{
    // Convert N to binary form
    String bin = "";
   
    // Loop to convert N
    // from Decimal to binary
    while (num > 0) {
        if (num % 2 == 1)
            bin += "1";
        else
            bin += "0";
        num /= 2;
    }
    bin = reverse(bin);
   
    // Initialising the table with -1.
    for(int i = 0; i < 32; i++){
        for(int j = 0; j < 2; j++){
            for(int l = 0; l < 2; l++)
                memo[i,j,l] = -1;
        }
    }
   
    // Calling the function
    return dp(0, 0, 0, bin);
}
static String reverse(String input) {
    char[] a = input.ToCharArray();
    int l, r = a.Length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.Join("",a);
}
  
// Driver code
public static void Main(String[] args)
{
    int N = 12;
    Console.Write(findints(N));
   
}
}
  
// This code contributed by Rajput-Ji

Javascript




<script>
 
// JavaScript program to count number of
// binary strings without consecutive 1’s
 
// Table to store the solution of
// every sub problem
var memo = Array.from(Array(32), ()=>Array(2));
 
for(var i =0;i<32;i++)
{
    for(var j =0; j<2; j++)
    {
        memo[i][j] = new Array(2).fill(-1);
    }
}
 
// Function to fill the table
/* Here,
   pos: keeps track of current position.
   f1: is the flag to check if current
         number is less than N or not.
   pr: represents the previous digit
*/
function dp(pos, fl, pr, bin)
{
    // Base case
    if (pos == bin.length)
        return 1;
 
    // Check if this subproblem
    // has already been solved
    if (memo[pos][fl][pr] != -1)
        return memo[pos][fl][pr];
 
    var val = 0;
 
    // Placing 0 at the current position
    // as it does not violate the condition
    if (bin[pos] == '0')
        val = val + dp(pos + 1, fl, 0, bin);
 
    // Here flag will be 1 for the
    // next recursive call
    else if (bin[pos] == '1')
        val = val + dp(pos + 1, 1, 0, bin);
 
    // Placing 1 at this position only if
    // the previously inserted number is 0
    if (pr == 0) {
 
        // If the number is smaller than N
        if (fl == 1) {
            val += dp(pos + 1, fl, 1, bin);
        }
 
        // If the digit at current position is 1
        else if (bin[pos] == '1') {
            val += dp(pos + 1, fl, 1, bin);
        }
    }
 
    // Storing the solution to this subproblem
    return memo[pos][fl][pr] = val;
}
 
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
function findIntegers(num)
{
    // Convert N to binary form
    var bin = "";
 
    // Loop to convert N
    // from Decimal to binary
    while (num > 0) {
        if (num % 2)
            bin += "1";
        else
            bin += "0";
        num =parseInt(num/2);
    }
 
    bin = bin.split('').reverse().join('')
 
 
    // Calling the function
    return dp(0, 0, 0, bin);
}
 
// Driver code
var N = 12;
document.write( findIntegers(N));
 
</script>
Output: 
8

 

Time Complexity: O(L * log(N)) 

  • O(log(N)) to convert the number from Decimal to binary.
  • O(L) to fill the table, where L is the length of the binary form.

 

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 experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :