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++ 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 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 |
# 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# 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 |
<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)
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++ 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 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));
}
} |
# 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))
|
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 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)); |
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).