Count possible binary strings of length N without P consecutive 0s and Q consecutive 1s
Last Updated :
13 Dec, 2022
Given three integers N, P, and Q, the task is to count all possible distinct binary strings of length N such that each binary string does not contain P times consecutive 0’s and Q times consecutive 1’s.
Examples:
Input: N = 5, P = 2, Q = 3
Output: 7
Explanation: Binary strings that satisfy the given conditions are { “01010”, “01011”, “01101”, “10101”, “10110”, “11010”, “11011”}. Therefore, the required output is 7.
Input: N = 5, P = 3, Q = 4
Output: 21
Naive Approach: The problem can be solved using Recursion. Following are the recurrence relations and their base cases :
At each possible index of a Binary String, either place the value ‘0‘ or place the value ‘1‘
Therefore, cntBinStr(str, N, P, Q) = cntBinStr(str + ‘0’, N, P, Q) + cntBinStr(str + ‘1’, N, P, Q)
where cntBinStr(str, N, P, Q) stores the count of distinct binary strings which does not contain P consecutive 1s and Q consecutive 0s.
Base Case: If length(str) == N, check if str satisfy the given condition or not. If found to be true, return 1. Otherwise, return 0.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool checkStr(string str,
int P, int Q)
{
int N = str.size();
char prev = str[0];
int cnt = 0;
for ( int i = 0; i < N;
i++) {
if (str[i] == prev) {
cnt++;
}
else {
if (prev == '1' && cnt >= Q) {
return false ;
}
if (prev == '0' && cnt >= P) {
return false ;
}
cnt = 1;
}
prev = str[i];
}
if (prev == '1' && cnt >= Q) {
return false ;
}
if (prev == '0' && cnt >= P) {
return false ;
}
return true ;
}
int cntBinStr(string str, int N,
int P, int Q)
{
int len = str.size();
if (len == N) {
if (checkStr(str, P, Q))
return 1;
return 0;
}
int X = cntBinStr(str + '0' ,
N, P, Q);
int Y = cntBinStr(str + '1' ,
N, P, Q);
return X + Y;
}
int main()
{
int N = 5, P = 2, Q = 3;
cout << cntBinStr( "" , N, P, Q);
return 0;
}
|
Java
import java.io.*;
class GFG{
static boolean checkStr(String str,
int P, int Q)
{
int N = str.length();
char prev = str.charAt( 0 );
int cnt = 0 ;
for ( int i = 0 ; i < N; i++)
{
if (str.charAt(i) == prev)
{
cnt++;
}
else
{
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
cnt = 1 ;
}
prev = str.charAt(i);
}
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
return true ;
}
static int cntBinStr(String str, int N,
int P, int Q)
{
int len = str.length();
if (len == N)
{
if (checkStr(str, P, Q))
return 1 ;
return 0 ;
}
int X = cntBinStr(str + '0' ,
N, P, Q);
int Y = cntBinStr(str + '1' ,
N, P, Q);
return X + Y;
}
public static void main (String[] args)
{
int N = 5 , P = 2 , Q = 3 ;
System.out.println(cntBinStr( "" , N, P, Q));
}
}
|
Python3
def checkStr( str , P, Q):
N = len ( str )
prev = str [ 0 ]
cnt = 0
for i in range (N):
if ( str [i] = = prev):
cnt + = 1
else :
if (prev = = '1' and
cnt > = Q):
return False
if (prev = = '0' and
cnt > = P):
return False
cnt = 1
prev = str [i]
if (prev = = '1' and
cnt > = Q):
return False
if (prev = = '0' and
cnt > = P):
return False
return True
def cntBinStr( str , N,
P, Q):
lenn = len ( str )
if (lenn = = N):
if (checkStr( str , P, Q)):
return 1
return 0
X = cntBinStr( str + '0' ,
N, P, Q)
Y = cntBinStr( str + '1' ,
N, P, Q)
return X + Y
if __name__ = = '__main__' :
N = 5
P = 2
Q = 3
print (cntBinStr("", N,
P, Q))
|
C#
using System;
class GFG{
static bool checkStr( string str,
int P, int Q)
{
int N = str.Length;
char prev = str[0];
int cnt = 0;
for ( int i = 0; i < N; i++)
{
if (str[i] == prev)
{
cnt++;
}
else
{
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
cnt = 1;
}
prev = str[i];
}
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
return true ;
}
static int cntBinStr( string str, int N,
int P, int Q)
{
int len = str.Length;
if (len == N)
{
if (checkStr(str, P, Q))
return 1;
return 0;
}
int X = cntBinStr(str + '0' ,
N, P, Q);
int Y = cntBinStr(str + '1' ,
N, P, Q);
return X + Y;
}
public static void Main ()
{
int N = 5, P = 2, Q = 3;
Console.WriteLine(cntBinStr( "" , N, P, Q));
}
}
|
Javascript
<script>
function checkStr(str, P, Q)
{
let N = str.length;
let prev = str[0];
let cnt = 0;
for (let i = 0; i < N; i++)
{
if (str[i] == prev)
{
cnt++;
}
else
{
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
cnt = 1;
}
prev = str[i];
}
if (prev == '1' && cnt >= Q)
{
return false ;
}
if (prev == '0' && cnt >= P)
{
return false ;
}
return true ;
}
function cntBinStr(str, N, P, Q)
{
let len = str.length;
if (len == N)
{
if (checkStr(str, P, Q))
return 1;
return 0;
}
let X = cntBinStr(str + '0' ,
N, P, Q);
let Y = cntBinStr(str + '1' ,
N, P, Q);
return X + Y;
}
let N = 5, P = 2, Q = 3;
document.write(cntBinStr( "" , N, P, Q));
</script>
|
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach the idea is to use Dynamic Programming. Follow the steps below to solve the problem:
- Initialize two 2D arrays, say zero[N][P] and one[N][Q].
- zero[i][j] stores the count of binary strings of length i having j consecutive 0’s. Fill all the value of zero[i][j] in bottom-up manner.
Insert 0 at the ith index.
Case 1: If (i – 1)th index of string contains 1.
Case 2: If (i – 1)th index of string contains 0.
for all r in the range [2, P – 1].
- one[i][j] stores the count of binary strings of length i having j consecutive 1’s. Fill all the value of zero[i][j] in bottom-up manner.
Insert 1 at the ith index.
Case 1: If (i-1)th index of string contains 0.
Case 2: If (i-1)th index of string contains 1.
for all j in the range [2, Q – 1].
- Finally, print count of subarrays that satisfy the given condition.
C++
#include <bits/stdc++.h>
using namespace std;
int cntBinStr( int N, int P, int Q)
{
int zero[N + 1][P];
int one[N + 1][Q];
memset (zero, 0, sizeof (zero));
memset (one, 0, sizeof (one));
zero[1][1] = one[1][1] = 1;
for ( int i = 2; i <= N; i++) {
for ( int j = 2; j < P;
j++) {
zero[i][j] = zero[i - 1][j - 1];
}
for ( int j = 1; j < Q;
j++) {
zero[i][1] = zero[i][1] + one[i - 1][j];
}
for ( int j = 2; j < Q;
j++) {
one[i][j] = one[i - 1][j - 1];
}
for ( int j = 1; j < P;
j++) {
one[i][1] = one[i][1] + zero[i - 1][j];
}
}
int res = 0;
for ( int i = 1; i < P; i++) {
res = res + zero[N][i];
}
for ( int i = 1; i < Q; i++) {
res = res + one[N][i];
}
return res;
}
int main()
{
int N = 5, P = 2, Q = 3;
cout << cntBinStr(N, P, Q);
return 0;
}
|
Java
import java.io.*;
class GFG{
static int cntBinStr( int N, int P, int Q)
{
int [][]zero = new int [N + 1 ][P];
int [][]one = new int [N + 1 ][Q];
zero[ 1 ][ 1 ] = one[ 1 ][ 1 ] = 1 ;
for ( int i = 2 ; i <= N; i++)
{
for ( int j = 2 ; j < P; j++)
{
zero[i][j] = zero[i - 1 ][j - 1 ];
}
for ( int j = 1 ; j < Q; j++)
{
zero[i][ 1 ] = zero[i][ 1 ] +
one[i - 1 ][j];
}
for ( int j = 2 ; j < Q; j++)
{
one[i][j] = one[i - 1 ][j - 1 ];
}
for ( int j = 1 ; j < P; j++)
{
one[i][ 1 ] = one[i][ 1 ] +
zero[i - 1 ][j];
}
}
int res = 0 ;
for ( int i = 1 ; i < P; i++)
{
res = res + zero[N][i];
}
for ( int i = 1 ; i < Q; i++)
{
res = res + one[N][i];
}
return res;
}
public static void main(String[] args)
{
int N = 5 , P = 2 , Q = 3 ;
System.out.print(cntBinStr(N, P, Q));
}
}
|
Python3
def cntBinStr(N, P, Q):
zero = [[ 0 for i in range (P)]
for j in range (N + 1 )];
one = [[ 0 for i in range (Q)]
for j in range (N + 1 )];
zero[ 1 ][ 1 ] = one[ 1 ][ 1 ] = 1 ;
for i in range ( 2 , N + 1 ):
for j in range ( 2 , P):
zero[i][j] = zero[i - 1 ][j - 1 ];
for j in range ( 1 , Q):
zero[i][ 1 ] = (zero[i][ 1 ] +
one[i - 1 ][j]);
for j in range ( 2 , Q):
one[i][j] = one[i - 1 ][j - 1 ];
for j in range ( 1 , P):
one[i][ 1 ] = one[i][ 1 ] + zero[i - 1 ][j];
res = 0 ;
for i in range ( 1 , P):
res = res + zero[N][i];
for i in range ( 1 , Q):
res = res + one[N][i];
return res;
if __name__ = = '__main__' :
N = 5 ;
P = 2 ;
Q = 3 ;
print (cntBinStr(N, P, Q));
|
C#
using System;
class GFG{
static int cntBinStr( int N, int P, int Q)
{
int [,]zero = new int [N + 1, P];
int [,]one = new int [N + 1, Q];
zero[1, 1] = one[1, 1] = 1;
for ( int i = 2; i <= N; i++)
{
for ( int j = 2; j < P; j++)
{
zero[i, j] = zero[i - 1, j - 1];
}
for ( int j = 1; j < Q; j++)
{
zero[i, 1] = zero[i, 1] +
one[i - 1, j];
}
for ( int j = 2; j < Q; j++)
{
one[i, j] = one[i - 1, j - 1];
}
for ( int j = 1; j < P; j++)
{
one[i, 1] = one[i, 1] +
zero[i - 1, j];
}
}
int res = 0;
for ( int i = 1; i < P; i++)
{
res = res + zero[N, i];
}
for ( int i = 1; i < Q; i++)
{
res = res + one[N, i];
}
return res;
}
public static void Main(String[] args)
{
int N = 5, P = 2, Q = 3;
Console.Write(cntBinStr(N, P, Q));
}
}
|
Javascript
<script>
function cntBinStr(N, P, Q)
{
var zero = new Array(N+1).fill(0).
map(item=>( new Array(P).fill(0)));
var one = new Array(N+1).fill(0).
map(item=>( new Array(Q).fill(0)));;
zero[1][1] = one[1][1] = 1;
for ( var i = 2; i <= N; i++) {
for ( var j = 2; j < P;
j++) {
zero[i][j] = zero[i - 1][j - 1];
}
for ( var j = 1; j < Q;
j++) {
zero[i][1] = zero[i][1] + one[i - 1][j];
}
for ( var j = 2; j < Q;
j++) {
one[i][j] = one[i - 1][j - 1];
}
for ( var j = 1; j < P;
j++) {
one[i][1] = one[i][1] + zero[i - 1][j];
}
}
var res = 0;
for ( var i = 1; i < P; i++) {
res = res + zero[N][i];
}
for ( var i = 1; i < Q; i++) {
res = res + one[N][i];
}
return res;
}
var N = 5, P = 2, Q = 3;
document.write( cntBinStr(N, P, Q));
</script>
|
Time complexity: O(N * (P + Q))
Auxiliary Space: O(N * (P + Q))
Share your thoughts in the comments
Please Login to comment...