Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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
import java.io.*;
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.

Auxiliary Space: O(32 * 2 * 2)
 

Efficient approach : DP tabulation (iterative)

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls. In this approach we use 3D DP store computation of subproblems and find the final result using iteration and not with the help of recursion.

Implementation Steps:

  • Convert the given number N to its binary representation.
  • Initialize a DP table of size n+1 x 2 x 2, where n is the number of digits in the binary representation of N.
  • Loop through each digit of the binary representation of N and fill the DP table using the recurrence relation: dp[i][j | (l < limit)][l] += dp[i-1][j][k], where dp[i][j][k] represents the number of binary strings of length i that do not have consecutive 1s, and j and k represent whether the previous digit and current digit are both 1s, respectively.
  • Sum up the number of valid binary strings of length N by adding dp[n][i][0] and dp[n][i][1] for i = 0 to 1.
  • Return the final count of valid binary strings.

Implementation:

C++




// C++ program to count number of
// binary strings without consecutive 1’s
 
#include <bits/stdc++.h>
using namespace std;
 
// 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());
 
    int n = bin.length();
 
    // DP table to store the solutions
    int dp[n + 1][2][2];
    memset(dp, 0, sizeof(dp));
 
    // Initializing the DP table
    dp[0][0][0] = 1;
 
    // Loop through each digit
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                int limit = (j ? 1 : bin[i - 1] - '0');
                for (int l = 0; l <= limit; l++) {
                    if (l == 1 && k == 1)
                        continue;
                    dp[i][j | (l < limit)][l] += dp[i - 1][j][k];
                }
            }
        }
    }
 
    // Calculating the result
    int result = 0;
    for (int i = 0; i < 2; i++) {
        result += dp[n][i][0];
        result += dp[n][i][1];
    }
     
      // return the final answer
    return result;
}
 
// Driver code
int main()
{
    int N = 12;
    cout << findIntegers(N);
 
    return 0;
}


Java




// Java code for above approach
 
import java.util.Arrays;
 
public class Main {
    // 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
        StringBuilder bin = new StringBuilder();
 
        // Loop to convert N
        // from Decimal to binary
        while (num > 0) {
            if (num % 2 == 1)
                bin.append("1");
            else
                bin.append("0");
            num /= 2;
        }
        bin.reverse();
        int n = bin.length();
 
        // DP table to store the solutions
        int[][][] dp = new int[n + 1][2][2];
        for (int[][] arr : dp) {
            for (int[] subArr : arr) {
                Arrays.fill(subArr, 0);
            }
        }
 
        // Initializing the DP table
        dp[0][0][0] = 1;
 
        // Loop through each digit
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 2; k++) {
                    int limit = (j == 1) ? 1 : (bin.charAt(i - 1) - '0');
                    for (int l = 0; l <= limit; l++) {
                        if (l == 1 && k == 1)
                            continue;
                        dp[i][j | ((l < limit) ? 1 : 0)][l] += dp[i - 1][j][k];
                    }
                }
            }
        }
 
        // Calculating the result
        int result = 0;
        for (int i = 0; i < 2; i++) {
            result += dp[n][i][0];
            result += dp[n][i][1];
        }
 
        return result;
    }
 
    // Driver code
    public static void main(String[] args) {
        int N = 12;
        System.out.println(findIntegers(N));
    }
}


Python3




# code
# Python3 program to count number of
# binary strings without consecutive 1’s
 
# 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 == 1:
            bin += "1"
        else:
            bin += "0"
        num //= 2
    bin = bin[::-1]
 
    n = len(bin)
 
    # DP table to store the solutions
    dp = [[[0 for i in range(2)] for j in range(2)] for k in range(n + 1)]
 
    # Initializing the DP table
    dp[0][0][0] = 1
 
    # Loop through each digit
    for i in range(1, n + 1):
        for j in range(2):
            for k in range(2):
                limit = 1 if j else int(bin[i - 1])
                for l in range(limit + 1):
                    if l == 1 and k == 1:
                        continue
                    dp[i][j | (l < limit)][l] += dp[i - 1][j][k]
 
    # Calculating the result
    result = 0
    for i in range(2):
        result += dp[n][i][0]
        result += dp[n][i][1]
 
    # return the final answer
    return result
 
 
# Driver code
N = 12
print(findIntegers(N))


C#




using System;
class GFG {
    // 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;
        }
        char[] binArray = bin.ToCharArray();
        Array.Reverse(binArray);
        bin = new string(binArray);
        int n = bin.Length;
 
        // DP table to store the solutions
        int[][][] dp = new int[n + 1][][];
        for (int i = 0; i <= n; i++) {
            dp[i] = new int[2][];
            for (int j = 0; j < 2; j++) {
                dp[i][j] = new int[2];
                for (int k = 0; k < 2; k++) {
                    dp[i][j][k] = 0;
                }
            }
        }
 
        // Initializing the DP table
        dp[0][0][0] = 1;
 
        // Loop through each digit
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 2; k++) {
                    int limit
                        = (j == 1) ? 1 : (bin[i - 1] - '0');
                    for (int l = 0; l <= limit; l++) {
                        if (l == 1 && k == 1)
                            continue;
                        dp[i][j | ((l < limit) ? 1 : 0)][l]
                            += dp[i - 1][j][k];
                    }
                }
            }
        }
 
        // Calculating the result
        int result = 0;
        for (int i = 0; i < 2; i++) {
            result += dp[n][i][0];
            result += dp[n][i][1];
        }
 
        return result;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int N = 12;
        Console.WriteLine(FindIntegers(N));
    }
}


Javascript




// Javascript 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
    let bin = "";
 
    // Loop to convert N
    // from Decimal to binary
    while (num > 0) {
        if (num % 2)
            bin += "1";
        else
            bin += "0";
        num = Math.floor(num / 2);
    }
    bin = bin.split("").reverse().join("");
 
    let n = bin.length;
 
    // DP table to store the solutions
    let dp = [];
    for (let i = 0; i <= n; i++) {
        dp[i] = [];
        for (let j = 0; j < 2; j++) {
            dp[i][j] = [];
            for (let k = 0; k < 2; k++) {
                dp[i][j][k] = 0;
            }
        }
    }
 
    // Initializing the DP table
    dp[0][0][0] = 1;
 
    // Loop through each digit
    for (let i = 1; i <= n; i++) {
        for (let j = 0; j < 2; j++) {
            for (let k = 0; k < 2; k++) {
                let limit = (j ? 1 : parseInt(bin[i - 1]));
                for (let l = 0; l <= limit; l++) {
                    if (l == 1 && k == 1)
                        continue;
                    dp[i][j | (l < limit)][l] += dp[i - 1][j][k];
                }
            }
        }
    }
 
    // Calculating the result
    let result = 0;
    for (let i = 0; i < 2; i++) {
        result += dp[n][i][0];
        result += dp[n][i][1];
    }
     
    // return the final answer
    return result;
}
 
// Driver code
let N = 12;
console.log(findIntegers(N));


Output

8



Time complexity: O(log N)
Auxiliary space: O(log N)

Explanation : 

  • The time complexity of the given code is O(log N), where N is the given input number. This is because the code loops through each digit of the binary representation of N, which has log N digits.
  • The space complexity of the given code is O(log N), as well. This is because the code uses a DP table of size n+1 x 2 x 2, where n is the number of digits in the binary representation of N (i.e., log N). Since each element in the table is an integer, the total space used by the DP table is O(log N).


Last Updated : 20 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads