Count ways to generate Binary String not containing “0100” Substring
Last Updated :
22 Mar, 2023
Given the number N, count the number of ways to create a binary string (the string that contains characters as zero or one) of size N such that it does not contain “0100” as a substring.
A substring is a contiguous sequence of characters within a string.
Examples:
Input: N = 4
Output: 15
Explanation: The answer will contain all possible substrings of size 4 except 0100 itself.
Input: N = 5
Output: 28
Naive approach: The article can be solved based on the following idea:
There are N positions to fill of binary string with either 1 or 0 while avoiding “0100” substring, for any position i recursive function will be called by setting that position with either 1 or 0 except when last three characters are 010 only recursive function is called for 1 (to form 0101) not for 0 since if 0 is called then 0100 will be present as a substring in given count of strings. Now to keep track of last three characters make use of bitmask.
Follow the steps below to solve the problem:
- Create a recursive function that takes two parameters one is the position that needs to fill and the other is the last three characters in form of a bitmask.
- Check the base cases. If the value of i is equal to N return 1.
- If the last three characters are not 010 Call the function recursively for 1 and 0, and sum up the values that are returned.
- else if the last three characters are 010 then call the function only for 1.
- return the value sum.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1;
int ans = 0LL;
if (i >= 3 and lastThreeDigits == 2) {
ans += recur(i + 1, 5, N);
}
else {
ans += recur(i + 1, lastThreeDigits << 1 & 7 | 1,
N);
ans += recur(i + 1, lastThreeDigits << 1 & 7, N);
}
return ans;
}
void countBinStrings( int N)
{
cout << recur(0, 0, N) << endl;
}
int main()
{
int N = 4;
countBinStrings(N);
int N1 = 5;
countBinStrings(N1);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1 ;
int ans = 0 ;
if (i >= 3 && lastThreeDigits == 2 )
{
ans += recur(i + 1 , 5 , N);
}
else {
ans += recur(i + 1 ,
lastThreeDigits << 1 & 7 | 1 , N);
ans += recur(i + 1 , lastThreeDigits << 1 & 7 ,
N);
}
return ans;
}
static void countBinStrings( int N)
{
System.out.println(recur( 0 , 0 , N));
}
public static void main(String[] args)
{
int N = 4 ;
countBinStrings(N);
int N1 = 5 ;
countBinStrings(N1);
}
}
|
Python3
def recur(i, lastThreeDigits, N):
if i = = N:
return 1
ans = 0
if i > = 3 and lastThreeDigits = = 2 :
ans + = recur(i + 1 , 5 , N)
else :
ans + = recur(i + 1 , (lastThreeDigits << 1 ) & 7 | 1 , N)
ans + = recur(i + 1 , (lastThreeDigits << 1 ) & 7 , N)
return ans
def countBinStrings(N):
print (recur( 0 , 0 , N))
N = 4
countBinStrings(N)
N1 = 5
countBinStrings(N1)
|
C#
using System;
using System.Collections.Generic;
public class Gfg {
static int recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1;
int ans = 0;
if (i >= 3 && lastThreeDigits == 2) {
ans += recur(i + 1, 5, N);
}
else {
ans += recur(i + 1, lastThreeDigits << 1 & 7 | 1,
N);
ans += recur(i + 1, lastThreeDigits << 1 & 7, N);
}
return ans;
}
static void countBinStrings( int N)
{
Console.WriteLine(recur(0, 0, N));
}
public static void Main( string [] args)
{
int N = 4;
countBinStrings(N);
int N1 = 5;
countBinStrings(N1);
}
}
|
Javascript
function recur(i, lastThreeDigits, N)
{
if (i == N)
return 1;
let ans = 0;
if (i >= 3 && lastThreeDigits == 2) {
ans += recur(i + 1, 5, N);
}
else {
ans += recur(i + 1, lastThreeDigits << 1 & 7 | 1,
N);
ans += recur(i + 1, lastThreeDigits << 1 & 7, N);
}
return ans;
}
function countBinStrings(N)
{
console.log(recur(0, 0, N));
}
let N = 4;
countBinStrings(N);
let N1 = 5;
countBinStrings(N1);
|
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
The idea is similar, but it can be observed that there are N * 8 states but the recursive function is called several times. That means that some states are called repeatedly. So the idea is to store the value of states. This can be done using recursive structure intact and just store the value in a HashMap and whenever the function is called, return the value store without computing .
Follow the steps below to solve the problem:
- Create a 2d array of dp[N + 1][8] initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][lastThreeDigits].
- If the answer for a particular state is already computed then just return dp[i][lastThreeDigits].
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int dp[100001][8];
int recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1;
if (dp[i][lastThreeDigits] != -1)
return dp[i][lastThreeDigits];
int ans = 0LL;
if (i >= 3 and lastThreeDigits == 2) {
ans += recur(i + 1, 5, N);
}
else {
ans += recur(i + 1, lastThreeDigits << 1 & 7 | 1,
N);
ans += recur(i + 1, lastThreeDigits << 1 & 7, N);
}
return dp[i][lastThreeDigits] = ans;
}
void countBinStrings( int N)
{
memset (dp, -1, sizeof (dp));
cout << recur(0, 0, N) << endl;
}
int main()
{
int N = 4;
countBinStrings(N);
int N1 = 5;
countBinStrings(N1);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int [][] dp= new int [ 100001 ][ 8 ];
static int recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1 ;
if (dp[i][lastThreeDigits] != - 1 )
return dp[i][lastThreeDigits];
int ans = 0 ;
if (i >= 3 && lastThreeDigits == 2 ) {
ans += recur(i + 1 , 5 , N);
}
else {
ans += recur(i + 1 , lastThreeDigits << 1 & 7 | 1 ,
N);
ans += recur(i + 1 , lastThreeDigits << 1 & 7 , N);
}
return dp[i][lastThreeDigits] = ans;
}
static void countBinStrings( int N)
{
for ( int i= 0 ;i<dp.length;i++)
{
for ( int j= 0 ;j<dp[ 0 ].length;j++)
{
dp[i][j]=- 1 ;
}
}
System.out.println(recur( 0 , 0 , N));
}
public static void main (String[] args)
{
int N = 4 ;
countBinStrings(N);
int N1 = 5 ;
countBinStrings(N1);
}
}
|
Python3
def recur(i, lastThreeDigits, N, dp):
if i = = N:
return 1
if dp[i][lastThreeDigits] ! = - 1 :
return dp[i][lastThreeDigits]
ans = 0
if i > = 3 and lastThreeDigits = = 2 :
ans + = recur(i + 1 , 5 , N, dp)
else :
ans + = recur(i + 1 , (lastThreeDigits << 1 ) & 7 | 1 ,
N, dp)
ans + = recur(i + 1 , (lastThreeDigits << 1 ) & 7 ,
N, dp)
dp[i][lastThreeDigits] = ans
return ans
def countBinStrings(N):
dp = [[ - 1 for j in range ( 8 )] for i in range ( 100001 )]
print (recur( 0 , 0 , N, dp))
if __name__ = = "__main__" :
N = 4
countBinStrings(N)
N1 = 5
countBinStrings(N1)
|
C#
using System;
public class GFG {
static int [, ] dp = new int [100001, 8];
static int Recur( int i, int lastThreeDigits, int N)
{
if (i == N)
return 1;
if (dp[i, lastThreeDigits] != -1)
return dp[i, lastThreeDigits];
int ans = 0;
if (i >= 3 && lastThreeDigits == 2) {
ans += Recur(i + 1, 5, N);
}
else {
ans += Recur(i + 1,
(lastThreeDigits << 1) & 7 | 1, N);
ans += Recur(i + 1, (lastThreeDigits << 1) & 7,
N);
}
return dp[i, lastThreeDigits] = ans;
}
static void CountBinStrings( int N)
{
for ( int i = 0; i < dp.GetLength(0); i++) {
for ( int j = 0; j < dp.GetLength(1); j++) {
dp[i, j] = -1;
}
}
Console.WriteLine(Recur(0, 0, N));
}
static public void Main()
{
int N = 4;
CountBinStrings(N);
int N1 = 5;
CountBinStrings(N1);
}
}
|
Javascript
let dp= new Array(100001);
for (let i=0; i<100001; i++)
dp[i]= new Array(8);
function recur( i, lastThreeDigits, N)
{
if (i == N)
return 1;
if (dp[i][lastThreeDigits] != -1)
return dp[i][lastThreeDigits];
let ans = 0;
if (i >= 3 && lastThreeDigits == 2) {
ans += recur(i + 1, 5, N);
}
else {
ans += recur(i + 1, lastThreeDigits << 1 & 7 | 1,
N);
ans += recur(i + 1, lastThreeDigits << 1 & 7, N);
}
return dp[i][lastThreeDigits] = ans;
}
function countBinStrings( N)
{
for (let i=0; i<100001; i++)
for (let j=0; j<8; j++)
dp[i][j]=-1;
console.log(recur(0, 0, N)+ "<br>" );
}
let N = 4;
countBinStrings(N);
let N1 = 5;
countBinStrings(N1);
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles :
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...