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.
![Rendered by QuickLaTeX.com zero[i][1] = \sum\limits_{j=1}^{Q - 1}one[i - 1][j]](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-b930e002b2bf7e3074b93baf352d56a6_l3.png)
Case 2: If (i – 1)th index of string contains 0.
![Rendered by QuickLaTeX.com zero[i][j] = zero[i-1][j-1]](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-5580cce2fc8299c7b32ac791bdec6513_l3.png)
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.
![Rendered by QuickLaTeX.com one[i][1] = \sum\limits_{j=1}^{P - 1}zero[i - 1][j]](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-8743c170976e6f94b86a81fc823b6d25_l3.png)
Case 2: If (i-1)th index of string contains 1.
![Rendered by QuickLaTeX.com one[i][j] = one[i-1][j-1]](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-90e8c18555d0420a6de700c6fc2e8153_l3.png)
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))
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
13 Dec, 2022
Like Article
Save Article