Count number of binary strings without consecutive 1’s : Set 2
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: 5
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 = 5Input: N = 12
Output: 8
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:
- Check if the previous digit is a 0 or 1.
- If it is a 0, then the present number can either be a 0 or 1.
- 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> |
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)