Generate all binary strings of length n with sub-string “01” appearing exactly twice
Given an integer N, the task is to generate all possible binary strings of length N which contain “01” as the sub-string exactly twice.
Examples:
Input: N = 4
Output:
0101
“0101” is the only binary string of length 4
that contains “01” exactly twice as the sub-string.
Input: N = 5
Output:
00101
01001
01010
01011
01101
10101
Approach: This problem can solved using backtracking. To generate a binary string, we implement a function that generate each bit at a time, update the state of the binary string (current length, number of occurrences of the pattern). Then call the function recursively, and according to the current state of the binary string, the function will decide how to generate the next bit or print out the binary string (if the problem’s requirement is met).
For this problem, backtracking strategy looks like we generate a binary tree with each node can have either value 0 or 1.
For example, with N = 4, the tree will look like:
Below is the implementation of the above approach:
C++
#include <iostream>
#include <stdlib.h>
using namespace std;
void printBinStr( int * str, int len)
{
for ( int i = 0; i < len; i++) {
cout << str[i];
}
cout << endl;
}
void generateBinStr( int * str, int len, int currlen,
int occur, int nextbit)
{
if (currlen == len) {
if (occur == 2 && nextbit == 0)
printBinStr(str, len);
return ;
}
if (currlen == 0) {
str[0] = nextbit;
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
}
else {
if (occur < 2) {
str[currlen] = nextbit;
if (str[currlen - 1] == 0 && nextbit == 1) {
occur += 1;
}
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
}
else {
if (str[currlen - 1] == 0 && nextbit == 1) {
return ;
}
else {
str[currlen] = nextbit;
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
}
}
}
}
int main()
{
int n = 5;
if (n < 4)
cout << -1;
else {
int * str = new int [n];
generateBinStr(str, n, 0, 0, 0);
generateBinStr(str, n, 0, 0, 1);
}
return 0;
}
|
Java
class GFG
{
static void printBinStr( int [] str, int len)
{
for ( int i = 0 ; i < len; i++)
{
System.out.print(str[i]);
}
System.out.println();
}
static void generateBinStr( int [] str, int len, int currlen,
int occur, int nextbit)
{
if (currlen == len)
{
if (occur == 2 && nextbit == 0 )
{
printBinStr(str, len);
}
return ;
}
if (currlen == 0 )
{
str[ 0 ] = nextbit;
generateBinStr(str, len, currlen + 1 , occur, 0 );
generateBinStr(str, len, currlen + 1 , occur, 1 );
} else
if (occur < 2 )
{
str[currlen] = nextbit;
if (str[currlen - 1 ] == 0 && nextbit == 1 )
{
occur += 1 ;
}
generateBinStr(str, len, currlen + 1 , occur, 0 );
generateBinStr(str, len, currlen + 1 , occur, 1 );
} else
if (str[currlen - 1 ] == 0 && nextbit == 1 )
{
return ;
}
else
{
str[currlen] = nextbit;
generateBinStr(str, len, currlen + 1 , occur, 0 );
generateBinStr(str, len, currlen + 1 , occur, 1 );
}
}
public static void main(String[] args)
{
int n = 5 ;
if (n < 4 )
{
System.out.print(- 1 );
}
else
{
int [] str = new int [n];
generateBinStr(str, n, 0 , 0 , 0 );
generateBinStr(str, n, 0 , 0 , 1 );
}
}
}
|
Python3
def printBinStr(string, length):
for i in range ( 0 , length):
print (string[i], end = "")
print ()
def generateBinStr(string, length, currlen,
occur, nextbit):
if currlen = = length:
if occur = = 2 and nextbit = = 0 :
printBinStr(string, length)
return
if currlen = = 0 :
string[ 0 ] = nextbit
generateBinStr(string, length,
currlen + 1 , occur, 0 )
generateBinStr(string, length,
currlen + 1 , occur, 1 )
else :
if occur < 2 :
string[currlen] = nextbit
if string[currlen - 1 ] = = 0 and nextbit = = 1 :
occur + = 1
generateBinStr(string, length,
currlen + 1 , occur, 0 )
generateBinStr(string, length,
currlen + 1 , occur, 1 )
else :
if string[currlen - 1 ] = = 0 and nextbit = = 1 :
return
else :
string[currlen] = nextbit
generateBinStr(string, length,
currlen + 1 , occur, 0 )
generateBinStr(string, length,
currlen + 1 , occur, 1 )
if __name__ = = "__main__" :
n = 5
if n < 4 :
print ( - 1 )
else :
string = [ None ] * n
generateBinStr(string, n, 0 , 0 , 0 )
generateBinStr(string, n, 0 , 0 , 1 )
|
C#
using System;
class GFG
{
static void printBinStr( int [] str, int len)
{
for ( int i = 0; i < len; i++)
{
Console.Write(str[i]);
}
Console.Write( "\n" );
}
static void generateBinStr( int [] str, int len, int currlen,
int occur, int nextbit)
{
if (currlen == len)
{
if (occur == 2 && nextbit == 0)
{
printBinStr(str, len);
}
return ;
}
if (currlen == 0)
{
str[0] = nextbit;
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
} else
if (occur < 2)
{
str[currlen] = nextbit;
if (str[currlen - 1] == 0 && nextbit == 1)
{
occur += 1;
}
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
} else
if (str[currlen - 1] == 0 && nextbit == 1)
{
return ;
}
else
{
str[currlen] = nextbit;
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
}
}
public static void Main(String[] args)
{
int n = 5;
if (n < 4)
{
Console.Write(-1);
}
else
{
int [] str = new int [n];
generateBinStr(str, n, 0, 0, 0);
generateBinStr(str, n, 0, 0, 1);
}
}
}
|
Javascript
<script>
function printBinStr(str, len)
{
for ( var i = 0; i < len; i++)
{
document.write(str[i]);
}
document.write( "<br>" );
}
function generateBinStr(str, len, currlen, occur, nextbit)
{
if (currlen == len)
{
if (occur == 2 && nextbit == 0)
printBinStr(str, len);
return ;
}
if (currlen == 0)
{
str[0] = nextbit;
generateBinStr(str, len, currlen + 1, occur, 0);
generateBinStr(str, len, currlen + 1, occur, 1);
}
else
{
if (occur < 2)
{
str[currlen] = nextbit;
if (str[currlen - 1] == 0 && nextbit == 1)
{
occur += 1;
}
generateBinStr(str, len,
currlen + 1, occur, 0);
generateBinStr(str, len,
currlen + 1, occur, 1);
}
else
{
if (str[currlen - 1] == 0 && nextbit == 1)
{
return ;
}
else
{
str[currlen] = nextbit;
generateBinStr(str, len,
currlen + 1, occur, 0);
generateBinStr(str, len,
currlen + 1, occur, 1);
}
}
}
}
var n = 5;
if (n < 4)
document.write(-1);
else
{
var str = Array(n);
generateBinStr(str, n, 0, 0, 0);
generateBinStr(str, n, 0, 0, 1);
}
</script>
|
Output
00101
01001
01010
01011
01101
10101
Time Complexity: O(2^n)
Auxiliary Space: O(2^n)
Approach 2:
Using an iterative method to generate all binary strings of length n
Step-by-step Explanation:
- Use a for loop to iterate over all integers from 0 to 2^n – 1.
- For each integer i, use the bitset class to convert it to a binary string of length n.
- Use the find method of the string class to check if the binary string contains the substring “01” exactly twice.
- If the binary string contains the substring “01” exactly twice, print it.
C++
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
int n = 5;
if (n < 4)
cout << -1 << endl;
else
{
for ( int i = 0; i < (1 << n); i++)
{
string s = bitset<32>(i).to_string();
s = s.substr(32 - n);
size_t first = s.find( "01" );
size_t second = s.find( "01" , first + 2);
if (first != string::npos && second != string::npos && s.find( "01" , second + 2) == string::npos)
cout << s << endl;
}
}
return 0;
}
|
Java
import java.util.BitSet;
public class GFG {
public static void main(String[] args)
{
int n = 5 ;
if (n < 4 )
System.out.println(- 1 );
else {
for ( int i = 0 ; i < ( 1 << n); i++) {
String s = Integer.toBinaryString(i);
while (s.length() < n) {
s = "0" + s;
}
String subsequence = "01" ;
int first = s.indexOf(subsequence);
int second
= s.indexOf(subsequence, first + 2 );
if (first != - 1 && second != - 1
&& s.indexOf(subsequence, second + 2 )
== - 1 ) {
System.out.println(s);
}
}
}
}
}
|
Python
def print_binary_combinations(n):
if n < 4 :
print ( - 1 )
else :
for i in range ( 1 << n):
binary_str = format (i, '0' + str (n) + 'b' )
binary_str = binary_str[ - n:]
first = binary_str.find( "01" )
second = binary_str.find( "01" , first + 2 )
if first ! = - 1 and second ! = - 1 and binary_str.find( "01" , second + 2 ) = = - 1 :
print (binary_str)
n = 5
print_binary_combinations(n)
|
C#
using System;
class GFG {
static void Main()
{
int n = 5;
if (n < 4)
Console.WriteLine(-1);
else {
for ( int i = 0; i < (1 << n); i++) {
string s = Convert.ToString(i, 2).PadLeft(
n, '0' );
int first = s.IndexOf( "01" );
int second = s.IndexOf( "01" , first + 2);
if (first != -1 && second != -1
&& s.IndexOf( "01" , second + 2) == -1)
Console.WriteLine(s);
}
}
}
}
|
Javascript
const n = 5;
if (n < 4) {
console.log(-1);
} else {
for (let i = 0; i < (1 << n); i++) {
let s = (i >>> 0).toString(2).padStart(32, '0' );
s = s.substr(32 - n);
const first = s.indexOf( "01" );
const second = s.indexOf( "01" , first + 2);
if (first !== -1 && second !== -1 && s.indexOf( "01" , second + 2) === -1) {
console.log(s);
}
}
}
|
Output
00101
01001
01010
01011
01101
10101
Time Complexity: O(2^n * n), where n is the length of the binary strings.
Auxiliary Space: O(n), where n is the length of the binary strings.
The time complexity is O(2^n * n) because the algorithm needs to generate all 2^n binary strings of length n and check each string for the substring “01”. The auxiliary space complexity is O(n) because the algorithm needs to store a single binary string at a time, and the length of a binary string is n.
How is this approach different from another approach?
The main difference between the original approach and the alternative approach using an iterative method is the way the binary strings are generated.
In the original approach, binary strings are generated recursively by calling the generateBinStr function. This function generates the next bit for a given binary string according to its current state and calls itself recursively to generate the remaining bits. This approach requires keeping track of the current length of the binary string, the number of occurrences of the substring “01”, and the next bit to be generated.
In contrast, the alternative approach using an iterative method generates binary strings by iterating over all integers from 0 to 2^n – 1 and converting each integer to a binary string using the bitset class. This approach is simpler and easier to understand because it doesn’t require recursion or keeping track of additional variables.
Both approaches have the same goal of generating all binary strings of length n that contain the substring “01” exactly twice. However, they use different methods to achieve this goal. The original approach has a lower time complexity of O(2^n) because it generates only valid binary strings, while the alternative approach has a higher time complexity of O(2^n * n) because it generates all 2^n binary strings and checks each one for validity.
Last Updated :
14 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...