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++
// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to check if a
// string satisfy the given
// condition or not
bool checkStr(string str,
int P, int Q)
{
// Stores the length
// of string
int N = str.size();
// Stores the previous
// character of the string
char prev = str[0];
// Stores the count of
// consecutive equal characters
int cnt = 0;
// Traverse the string
for (int i = 0; i < N;
i++) {
// If current character
// is equal to the
// previous character
if (str[i] == prev) {
cnt++;
}
else {
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q) {
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P) {
return false;
}
// Reset value of cnt
cnt = 1;
}
prev = str[i];
}
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q) {
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P) {
return false;
}
return true;
}
// Function to count all distinct
// binary strings that satisfy
// the given condition
int cntBinStr(string str, int N,
int P, int Q)
{
// Stores the length of str
int len = str.size();
// If length of str is N
if (len == N) {
// If str satisfy
// the given condition
if (checkStr(str, P, Q))
return 1;
// If str does not satisfy
// the given condition
return 0;
}
// Append a character '0' at
// end of str
int X = cntBinStr(str + '0',
N, P, Q);
// Append a character '1' at
// end of str
int Y = cntBinStr(str + '1',
N, P, Q);
// Return total count
// of binary strings
return X + Y;
}
// Driver Code
int main()
{
int N = 5, P = 2, Q = 3;
cout << cntBinStr("", N, P, Q);
return 0;
}
Java
// Java program to implement
// the above approach
import java.io.*;
class GFG{
// Function to check if a
// string satisfy the given
// condition or not
static boolean checkStr(String str,
int P, int Q)
{
// Stores the length
// of string
int N = str.length();
// Stores the previous
// character of the string
char prev = str.charAt(0);
// Stores the count of
// consecutive equal characters
int cnt = 0;
// Traverse the string
for(int i = 0; i < N; i++)
{
// If current character
// is equal to the
// previous character
if (str.charAt(i) == prev)
{
cnt++;
}
else
{
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
// Reset value of cnt
cnt = 1;
}
prev = str.charAt(i);
}
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
return true;
}
// Function to count all distinct
// binary strings that satisfy
// the given condition
static int cntBinStr(String str, int N,
int P, int Q)
{
// Stores the length of str
int len = str.length();
// If length of str is N
if (len == N)
{
// If str satisfy
// the given condition
if (checkStr(str, P, Q))
return 1;
// If str does not satisfy
// the given condition
return 0;
}
// Append a character '0' at
// end of str
int X = cntBinStr(str + '0',
N, P, Q);
// Append a character '1' at
// end of str
int Y = cntBinStr(str + '1',
N, P, Q);
// Return total count
// of binary strings
return X + Y;
}
// Driver Code
public static void main (String[] args)
{
int N = 5, P = 2, Q = 3;
System.out.println(cntBinStr("", N, P, Q));
}
}
// This code is contributed by code_hunt
Python3
# Python3 program to implement
# the above approach
# Function to check if a
# satisfy the given
# condition or not
def checkStr(str, P, Q):
# Stores the length
# of string
N = len(str)
# Stores the previous
# character of the string
prev = str[0]
# Stores the count of
# consecutive equal
# characters
cnt = 0
# Traverse the string
for i in range(N):
# If current character
# is equal to the
# previous character
if (str[i] == prev):
cnt += 1
else:
# If count of consecutive
# 1s is more than Q
if (prev == '1' and
cnt >= Q):
return False
# If count of consecutive
# 0s is more than P
if (prev == '0' and
cnt >= P):
return False
# Reset value of cnt
cnt = 1
prev = str[i]
# If count of consecutive
# 1s is more than Q
if (prev == '1'and
cnt >= Q):
return False
# If count of consecutive
# 0s is more than P
if (prev == '0' and
cnt >= P):
return False
return True
# Function to count all
# distinct binary strings
# that satisfy the given
# condition
def cntBinStr(str, N,
P, Q):
# Stores the length
# of str
lenn = len(str)
# If length of str
# is N
if (lenn == N):
# If str satisfy
# the given condition
if (checkStr(str, P, Q)):
return 1
# If str does not satisfy
# the given condition
return 0
# Append a character '0'
# at end of str
X = cntBinStr(str + '0',
N, P, Q)
# Append a character
# '1' at end of str
Y = cntBinStr(str + '1',
N, P, Q)
# Return total count
# of binary strings
return X + Y
# Driver Code
if __name__ == '__main__':
N = 5
P = 2
Q = 3
print(cntBinStr("", N,
P, Q))
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to check if a
// string satisfy the given
// condition or not
static bool checkStr(string str,
int P, int Q)
{
// Stores the length
// of string
int N = str.Length;
// Stores the previous
// character of the string
char prev = str[0];
// Stores the count of
// consecutive equal characters
int cnt = 0;
// Traverse the string
for(int i = 0; i < N; i++)
{
// If current character
// is equal to the
// previous character
if (str[i] == prev)
{
cnt++;
}
else
{
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
// Reset value of cnt
cnt = 1;
}
prev = str[i];
}
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
return true;
}
// Function to count all distinct
// binary strings that satisfy
// the given condition
static int cntBinStr(string str, int N,
int P, int Q)
{
// Stores the length of str
int len = str.Length;
// If length of str is N
if (len == N)
{
// If str satisfy
// the given condition
if (checkStr(str, P, Q))
return 1;
// If str does not satisfy
// the given condition
return 0;
}
// Append a character '0' at
// end of str
int X = cntBinStr(str + '0',
N, P, Q);
// Append a character '1' at
// end of str
int Y = cntBinStr(str + '1',
N, P, Q);
// Return total count
// of binary strings
return X + Y;
}
// Driver Code
public static void Main ()
{
int N = 5, P = 2, Q = 3;
Console.WriteLine(cntBinStr("", N, P, Q));
}
}
// This code is contributed by sanjoy_62
JavaScript
<script>
// Javascript program to implement
// the above approach
// Function to check if a
// string satisfy the given
// condition or not
function checkStr(str, P, Q)
{
// Stores the length
// of string
let N = str.length;
// Stores the previous
// character of the string
let prev = str[0];
// Stores the count of
// consecutive equal characters
let cnt = 0;
// Traverse the string
for(let i = 0; i < N; i++)
{
// If current character
// is equal to the
// previous character
if (str[i] == prev)
{
cnt++;
}
else
{
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
// Reset value of cnt
cnt = 1;
}
prev = str[i];
}
// If count of consecutive
// 1s is more than Q
if (prev == '1' && cnt >= Q)
{
return false;
}
// If count of consecutive
// 0s is more than P
if (prev == '0' && cnt >= P)
{
return false;
}
return true;
}
// Function to count all distinct
// binary strings that satisfy
// the given condition
function cntBinStr(str, N, P, Q)
{
// Stores the length of str
let len = str.length;
// If length of str is N
if (len == N)
{
// If str satisfy
// the given condition
if (checkStr(str, P, Q))
return 1;
// If str does not satisfy
// the given condition
return 0;
}
// Append a character '0' at
// end of str
let X = cntBinStr(str + '0',
N, P, Q);
// Append a character '1' at
// end of str
let Y = cntBinStr(str + '1',
N, P, Q);
// Return total count
// of binary strings
return X + Y;
}
// Driver Code
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.
zero[i][1] = \sum\limits_{j=1}^{Q - 1}one[i - 1][j]
Case 2: If (i - 1)th index of string contains 0.
zero[i][j] = zero[i-1][j-1]
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.
one[i][1] = \sum\limits_{j=1}^{P - 1}zero[i - 1][j]
Case 2: If (i-1)th index of string contains 1.
one[i][j] = one[i-1][j-1]
for all j in the range [2, Q - 1].
- Finally, print count of subarrays that satisfy the given condition.
C++
// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count binary strings
// that satisfy the given condition
int cntBinStr(int N, int P, int Q)
{
// zero[i][j] stores count
// of binary strings of length i
// having j consecutive 0s
int zero[N + 1][P];
// one[i][j] stores count
// of binary strings of length i
// having j consecutive 1s
int one[N + 1][Q];
// Set all values of
// zero[][] array to 0
memset(zero, 0, sizeof(zero));
// Set all values of
// one[i][j] array to 0
memset(one, 0, sizeof(one));
// Base case
zero[1][1] = one[1][1] = 1;
// Fill all the values of zero[i][j]
// and one[i][j] in bottom up manner
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];
}
}
// Stores count of binary strings
// that satisfy the given condition
int res = 0;
// Count binary strings of
// length N having less than
// P consecutive 0s
for (int i = 1; i < P; i++) {
res = res + zero[N][i];
}
// Count binary strings of
// length N having less than
// Q consecutive 1s
for (int i = 1; i < Q; i++) {
res = res + one[N][i];
}
return res;
}
// Driver Code
int main()
{
int N = 5, P = 2, Q = 3;
cout << cntBinStr(N, P, Q);
return 0;
}
Java
// Java program to implement
// the above approach
import java.io.*;
class GFG{
// Function to count binary Strings
// that satisfy the given condition
static int cntBinStr(int N, int P, int Q)
{
// zero[i][j] stores count
// of binary Strings of length i
// having j consecutive 0s
int [][]zero = new int[N + 1][P];
// one[i][j] stores count
// of binary Strings of length i
// having j consecutive 1s
int [][]one = new int[N + 1][Q];
// Base case
zero[1][1] = one[1][1] = 1;
// Fill all the values of zero[i][j]
// and one[i][j] in bottom up manner
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];
}
}
// Stores count of binary Strings
// that satisfy the given condition
int res = 0;
// Count binary Strings of
// length N having less than
// P consecutive 0s
for(int i = 1; i < P; i++)
{
res = res + zero[N][i];
}
// Count binary Strings of
// length N having less than
// Q consecutive 1s
for(int i = 1; i < Q; i++)
{
res = res + one[N][i];
}
return res;
}
// Driver Code
public static void main(String[] args)
{
int N = 5, P = 2, Q = 3;
System.out.print(cntBinStr(N, P, Q));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program to implement
# the above approach
# Function to count binary
# Strings that satisfy the
# given condition
def cntBinStr(N, P, Q):
# zero[i][j] stores count
# of binary Strings of length i
# having j consecutive 0s
zero = [[0 for i in range(P)]
for j in range(N + 1)];
# one[i][j] stores count
# of binary Strings of length i
# having j consecutive 1s
one = [[0 for i in range(Q)]
for j in range(N + 1)];
# Base case
zero[1][1] = one[1][1] = 1;
# Fill all the values of
# zero[i][j] and one[i][j]
# in bottom up manner
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];
# Stores count of binary
# Strings that satisfy
# the given condition
res = 0;
# Count binary Strings of
# length N having less than
# P consecutive 0s
for i in range(1, P):
res = res + zero[N][i];
# Count binary Strings of
# length N having less than
# Q consecutive 1s
for i in range(1, Q):
res = res + one[N][i];
return res;
# Driver Code
if __name__ == '__main__':
N = 5;
P = 2;
Q = 3;
print(cntBinStr(N, P, Q));
# This code is contributed by gauravrajput1
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to count binary Strings
// that satisfy the given condition
static int cntBinStr(int N, int P, int Q)
{
// zero[i,j] stores count
// of binary Strings of length i
// having j consecutive 0s
int [,]zero = new int[N + 1, P];
// one[i,j] stores count
// of binary Strings of length i
// having j consecutive 1s
int [,]one = new int[N + 1, Q];
// Base case
zero[1, 1] = one[1, 1] = 1;
// Fill all the values of zero[i,j]
// and one[i,j] in bottom up manner
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];
}
}
// Stores count of binary Strings
// that satisfy the given condition
int res = 0;
// Count binary Strings of
// length N having less than
// P consecutive 0s
for(int i = 1; i < P; i++)
{
res = res + zero[N, i];
}
// Count binary Strings of
// length N having less than
// Q consecutive 1s
for(int i = 1; i < Q; i++)
{
res = res + one[N, i];
}
return res;
}
// Driver Code
public static void Main(String[] args)
{
int N = 5, P = 2, Q = 3;
Console.Write(cntBinStr(N, P, Q));
}
}
// This code is contributed by gauravrajput1
JavaScript
<script>
// JavaScript program to implement
// the above approach
// Function to count binary strings
// that satisfy the given condition
function cntBinStr(N, P, Q)
{
// zero[i][j] stores count
// of binary strings of length i
// having j consecutive 0s
//and
// Set all values of
// zero[][] array to 0
var zero = new Array(N+1).fill(0).
map(item=>(new Array(P).fill(0)));
// one[i][j] stores count
// of binary strings of length i
// having j consecutive 1s
//and
// Set all values of
// one[i][j] array to 0
var one = new Array(N+1).fill(0).
map(item=>(new Array(Q).fill(0)));;
// Base case
zero[1][1] = one[1][1] = 1;
// Fill all the values of zero[i][j]
// and one[i][j] in bottom up manner
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];
}
}
// Stores count of binary strings
// that satisfy the given condition
var res = 0;
// Count binary strings of
// length N having less than
// P consecutive 0s
for (var i = 1; i < P; i++) {
res = res + zero[N][i];
}
// Count binary strings of
// length N having less than
// Q consecutive 1s
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));
// This code in contributed by SoumikMondal
</script>
Time complexity: O(N * (P + Q))
Auxiliary Space: O(N * (P + Q))
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Dijkstra's Algorithm to find Shortest Paths from a Source to all Given a weighted undirected graph represented as an edge list and a source vertex src, find the shortest path distances from the source vertex to all other vertices in the graph. The graph contains V vertices, numbered from 0 to V - 1.Note: The given graph does not contain any negative edge. Example
12 min read
Selection Sort Selection Sort is a comparison-based sorting algorithm. It sorts an array by repeatedly selecting the smallest (or largest) element from the unsorted portion and swapping it with the first unsorted element. This process continues until the entire array is sorted.First we find the smallest element an
8 min read