Count valid strings that contains '0', '1' or '2'
Last Updated :
04 Mar, 2024
Given an integer n(1 <= n <= 105), the task is to count valid string S of length n, which contains characters '0', '1', or '2' only. For a valid string, it must follow the below conditions.
- There should not be more than K1 occurrences of '0'.
- There should not be more than K2 consecutive '1's. (1 <= K1, K2 <= 10)
Note: The answer may be very large, so return it modulo 109 + 7.
Examples:
Input: n = 2, K1 = 1, K2 = 2
Output: 8
Explanation: There are 8 valid strings of length 2: "22", "02", "20", "12", "21", "01", "10", "11". "00" is not valid string because there should not be more than one occurrence of '0'.
Input: n = 5, K1 = 2, K2 = 3;
Output: 139
Input: n = n = 1012, K1 = 3, K2 = 5
Output: 663818944
Counting valid strings that contain '0', '1', or '2' using Recursion:
- Base Case: When n becomes 0, this indicates that a valid string of the desired length has been generated. So, return 1.
- Within the countValidString() function, iterates over the three possible characters: '0', '1', and '2'. For each character, checks if it can be added to the string based on the constraints:
- If zeroCount < K1, we can add '0' to the string. So, recur for rest of the length and store result in res1.
- If oneCount < K2, we can add '1' to the string. So, recur for rest of the length and store result in res2.
- We can always add '2' to the string. So, recur for rest of the length and store result in res3.
- Finally, return the overall result = (res1 + res2 + res3) % 1e9+7.
Below is the implementation of the above approach:
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Define a modulo value
int mod = 1e9 + 7;
// Recursive function to calculate the number
// of valid strings
int countValidString(int zeroCount, int oneCount, int K1,
int K2, int n)
{
// Base case: If n becomes 0, return 1
// as a valid record is found
if (n == 0)
return 1;
// Initialize variables to store
// different results
long long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible
// characters: 0, 1, and 2
for (int i = 0; i <= 2; i++) {
// Check if we can add '0' to
// the string (zeroCount < K1)
if (zeroCount < K1 && i == 0) {
res1 = countValidString(zeroCount + 1, 0, K1,
K2, n - 1);
}
// Check if we can add '1' to the
// string (oneCount < K2)
if (oneCount < K2 && i == 1) {
res2 = countValidString(zeroCount, oneCount + 1,
K1, K2, n - 1);
}
// Add '2' to the string
res3
= countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Return the sum modulo 'mod'
return (res1 + res2 + res3) % mod;
}
// Drivers code
int main()
{
int n = 2, K1 = 1, K2 = 2;
// Call the solve function to calculate
// the valid strings
cout << countValidString(0, 0, K1, K2, n);
return 0;
}
Java
public class ValidStrings {
// Define a modulo value
static int mod = (int) 1e9 + 7;
// Recursive function to calculate the number
// of valid strings
static long countValidString(int zeroCount, int oneCount, int K1, int K2, int n) {
// Base case: If n becomes 0, return 1
// as a valid record is found
if (n == 0)
return 1;
// Initialize variables to store different results
long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible characters: 0, 1, and 2
for (int i = 0; i <= 2; i++) {
// Check if we can add '0' to the string (zeroCount < K1)
if (zeroCount < K1 && i == 0) {
res1 = countValidString(zeroCount + 1, 0, K1, K2, n - 1);
}
// Check if we can add '1' to the string (oneCount < K2)
if (oneCount < K2 && i == 1) {
res2 = countValidString(zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Return the sum modulo 'mod'
return (res1 + res2 + res3) % mod;
}
// Driver code
public static void main(String[] args) {
int n = 2, K1 = 1, K2 = 2;
// Call the countValidString function to calculate the valid strings
System.out.println(countValidString(0, 0, K1, K2, n));
}
}
//Contributed by Aditi Tyagi
C#
using System;
class Program
{
// Define a modulo value
const int mod = 1000000007;
// Recursive function to calculate the number
// of valid strings
static long CountValidString(int zeroCount, int oneCount, int K1, int K2, int n)
{
// Base case: If n becomes 0, return 1
// as a valid record is found
if (n == 0)
return 1;
// Initialize variables to store different results
long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible characters: 0, 1, and 2
for (int i = 0; i <= 2; i++)
{
// Check if we can add '0' to the string (zeroCount < K1)
if (zeroCount < K1 && i == 0)
{
res1 = CountValidString(zeroCount + 1, 0, K1, K2, n - 1);
}
// Check if we can add '1' to the string (oneCount < K2)
if (oneCount < K2 && i == 1)
{
res2 = CountValidString(zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = CountValidString(zeroCount, 0, K1, K2, n - 1);
}
// Return the sum modulo 'mod'
return (res1 + res2 + res3) % mod;
}
// Driver code
static void Main()
{
int n = 2, K1 = 1, K2 = 2;
// Call the CountValidString function to calculate the valid strings
Console.WriteLine(CountValidString(0, 0, K1, K2, n));
}
}
JavaScript
// JavaScript code for the above approach:
// Define a modulo value
const mod = 1e9 + 7;
// Recursive function to calculate the number
// of valid strings
function countValidString(zeroCount, oneCount, K1, K2, n) {
// Base case: If n becomes 0, return 1
// as a valid record is found
if (n === 0) {
return 1;
}
// Initialize variables to store
// different results
let res1 = 0,
res2 = 0,
res3 = 0;
// Iterate over three possible
// characters: 0, 1, and 2
for (let i = 0; i <= 2; i++) {
// Check if we can add '0' to
// the string (zeroCount < K1)
if (zeroCount < K1 && i === 0) {
res1 = countValidString(zeroCount + 1, 0, K1, K2, n - 1);
}
// Check if we can add '1' to the
// string (oneCount < K2)
if (oneCount < K2 && i === 1) {
res2 = countValidString(zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Return the sum modulo 'mod'
return (res1 + res2 + res3) % mod;
}
// Drivers code
const n = 2,
K1 = 1,
K2 = 2;
// Call the solve function to calculate
// the valid strings
console.log(countValidString(0, 0, K1, K2, n));
Python3
# Define a modulo value
mod = 10**9 + 7
# Recursive function to calculate the number
# of valid strings
def countValidString(zeroCount, oneCount, K1, K2, n):
# Base case: If n becomes 0, return 1
# as a valid record is found
if n == 0:
return 1
# Initialize variables to store
# different results
res1 = 0
res2 = 0
res3 = 0
# Iterate over three possible
# characters: 0, 1, and 2
for i in range(3):
# Check if we can add '0' to
# the string (zeroCount < K1)
if zeroCount < K1 and i == 0:
res1 = countValidString(zeroCount + 1, 0, K1, K2, n - 1)
# Check if we can add '1' to the
# string (oneCount < K2)
if oneCount < K2 and i == 1:
res2 = countValidString(zeroCount, oneCount + 1, K1, K2, n - 1)
# Add '2' to the string
res3 = countValidString(zeroCount, 0, K1, K2, n - 1)
# Return the sum modulo 'mod'
return (res1 + res2 + res3) % mod
# Drivers code
if __name__ == "__main__":
n = 2
K1 = 1
K2 = 2
# Call the solve function to calculate
# the valid strings
print(countValidString(0, 0, K1, K2, n))
Time Complexity: O(3^n), where 'n' is the length of the string.
Auxiliary Space: O(n)
Counting valid strings that contains '0', '1', or '2' using Dynamic Programming (Memoization):
Explore the valid string using recursion and memoize the subproblems. The state includes the counts of '0's and consecutive '1's, and recursion explores character choices ('0', '1', '2') for valid strings, we also keep maintain the constraints like no more than K1 '0' and no K2 consecutive '1's. Finally, add valid answers to result and return the result by taking modulo.
Step-by-step approach:
- Use a three dimensional dp[zeroCount][oneCount][n1], which represents the result of subproblem when the count of zero was zeroCount, the count of one was oneCount for n1 length string.
- Base Case: When n becomes 0, this indicates that a valid string of the desired length has been generated. So, return 1.
- Within the countValidString() function, iterates over the three possible characters: '0', '1', and '2'. For each character, checks if it can be added to the string based on the constraints:
- If zeroCount < K1, we can add '0' to the string. So, recur for rest of the length and store result in res1.
- If oneCount < K2, we can add '1' to the string. So, recur for rest of the length and store result in res2.
- We can always add '2' to the string. So, recur for rest of the length and store result in res3.
- Finally, store the overall result in dp before returning result = (res1 + res2 + res3) % 1e9+7.
Below is the implementation of the above approch:
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Define a 3D array for memoization
int dp[10][10][100005];
// Define a modulo value
int mod = 1e9 + 7;
// Recursive function to calculate the
// number of valid strings
int countValidString(int zeroCount, int oneCount, int K1,
int K2, int n)
{
// Base case: If n becomes 0, return 1
// as a valid record is found
if (n == 0)
return 1;
// If the result for the current state
// is already calculated, return it
if (dp[zeroCount][oneCount][n] != -1)
return dp[zeroCount][oneCount][n];
// Initialize variables to
// store different results
long long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible
// characters: 0, 1, and 2
for (int i = 0; i <= 2; i++) {
// Check if we can add '0' to
// the string (zeroCount < K1)
if (zeroCount < K1 && i == 0) {
res1 = countValidString(zeroCount + 1, 0, K1,
K2, n - 1);
}
// Check if we can add '1' to the
// string (oneCount < K2)
if (oneCount < K2 && i == 1) {
res2 = countValidString(zeroCount, oneCount + 1,
K1, K2, n - 1);
}
// Add '2' to the string
res3
= countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Store the result in the memoization
// table and return the sum modulo 'mod'
return dp[zeroCount][oneCount][n]
= (res1 + res2 + res3) % mod;
}
// Drivers code
int main()
{
int n = 1012, K1 = 3, K2 = 5;
// Initialize the memoization table with -1
memset(dp, -1, sizeof(dp));
// Call the solve function to calculate
// the valid strings
cout << countValidString(0, 0, K1, K2, n);
return 0;
}
Java
import java.util.Arrays;
public class ValidStrings {
// Define a 3D array for memoization
static long[][][] dp = new long[10][10][100005];
// Define a modulo value
static int mod = (int) 1e9 + 7;
// Recursive function to calculate the number of valid strings
static long countValidString(int zeroCount, int oneCount, int K1, int K2, int n) {
// Base case: If n becomes 0, return 1 as a valid record is found
if (n == 0)
return 1;
// If the result for the current state is already calculated, return it
if (dp[zeroCount][oneCount][n] != -1)
return dp[zeroCount][oneCount][n];
// Initialize variables to store different results
long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible characters: 0, 1, and 2
for (int i = 0; i <= 2; i++) {
// Check if we can add '0' to the string (zeroCount < K1)
if (zeroCount < K1 && i == 0) {
res1 = countValidString(zeroCount + 1, 0, K1, K2, n - 1);
}
// Check if we can add '1' to the string (oneCount < K2)
if (oneCount < K2 && i == 1) {
res2 = countValidString(zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Store the result in the memoization table and return the sum modulo 'mod'
return dp[zeroCount][oneCount][n] = (res1 + res2 + res3) % mod;
}
// Main method
public static void main(String[] args) {
int n = 1012, K1 = 3, K2 = 5;
// Initialize the memoization table with -1
for (long[][] row1 : dp) {
for (long[] row2 : row1) {
Arrays.fill(row2, -1);
}
}
// Call the function to calculate the valid strings
System.out.println(countValidString(0, 0, K1, K2, n));
}
}
C#
// C# program for the above approach
using System;
public class ValidStrings {
// Define a 3D array for memoization
static long[, , ] dp = new long[10, 10, 100005];
// Define a modulo value
static int mod = (int)1e9 + 7;
// Recursive function to calculate the number of valid
// strings
static long CountValidString(int zeroCount,
int oneCount, int K1,
int K2, int n)
{
// Base case: If n becomes 0, return 1 as a valid
// record is found
if (n == 0)
return 1;
// If the result for the current state is already
// calculated, return it
if (dp[zeroCount, oneCount, n] != -1)
return dp[zeroCount, oneCount, n];
// Initialize variables to store different results
long res1 = 0, res2 = 0, res3 = 0;
// Iterate over three possible characters: 0, 1, and
// 2
for (int i = 0; i <= 2; i++) {
// Check if we can add '0' to the string
// (zeroCount < K1)
if (zeroCount < K1 && i == 0) {
res1 = CountValidString(zeroCount + 1, 0,
K1, K2, n - 1);
}
// Check if we can add '1' to the string
// (oneCount < K2)
if (oneCount < K2 && i == 1) {
res2 = CountValidString(
zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = CountValidString(zeroCount, 0, K1, K2,
n - 1);
}
// Store the result in the memoization table and
// return the sum modulo 'mod'
return dp[zeroCount, oneCount, n]
= (res1 + res2 + res3) % mod;
}
// Main method
public static void Main(string[] args)
{
int n = 1012, K1 = 3, K2 = 5;
// Initialize the memoization table with -1
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 100005; k++) {
dp[i, j, k] = -1;
}
}
}
// Call the function to calculate the valid strings
Console.WriteLine(
CountValidString(0, 0, K1, K2, n));
}
}
// This code is contributed by Susobhan Akhuli
JavaScript
// Javascript program for the above approach
// Define a 3D array for memoization
const dp = Array.from({ length: 10 }, () =>
Array.from({ length: 10 }, () => Array(100005).fill(-1))
);
// Define a modulo value
const mod = 1e9 + 7;
// Recursive function to calculate the number of valid strings
function countValidString(zeroCount, oneCount, K1, K2, n) {
// Base case: If n becomes 0, return 1 as a valid record is found
if (n === 0) return 1;
// If the result for the current state is already calculated, return it
if (dp[zeroCount][oneCount][n] !== -1) return dp[zeroCount][oneCount][n];
// Initialize variables to store different results
let res1 = 0,
res2 = 0,
res3 = 0;
// Iterate over three possible characters: 0, 1, and 2
for (let i = 0; i <= 2; i++) {
// Check if we can add '0' to the string (zeroCount < K1)
if (zeroCount < K1 && i === 0) {
res1 = countValidString(zeroCount + 1, 0, K1, K2, n - 1);
}
// Check if we can add '1' to the string (oneCount < K2)
if (oneCount < K2 && i === 1) {
res2 = countValidString(zeroCount, oneCount + 1, K1, K2, n - 1);
}
// Add '2' to the string
res3 = countValidString(zeroCount, 0, K1, K2, n - 1);
}
// Store the result in the memoization table and return the sum modulo 'mod'
return (dp[zeroCount][oneCount][n] = (res1 + res2 + res3) % mod);
}
const n = 1012,
K1 = 3,
K2 = 5;
// Initialize the memoization table with -1
dp.forEach((row1) => {
row1.forEach((row2) => {
row2.fill(-1);
});
});
// Call the function to calculate the valid strings
console.log(countValidString(0, 0, K1, K2, n));
// This code is contributed by Susobhan Akhuli
Python3
import sys
# Increase recursion limit to avoid RecursionError
sys.setrecursionlimit(10**6)
# Define a 3D array for memoization
dp = [[[None for _ in range(100005)] for _ in range(10)] for _ in range(10)]
# Define a modulo value
mod = int(1e9 + 7)
# Recursive function to calculate the number of valid strings
def count_valid_string(zero_count, one_count, K1, K2, n):
# Base case: If n becomes 0, return 1 as a valid record is found
if n == 0:
return 1
# If the result for the current state is already calculated, return it
if dp[zero_count][one_count][n] is not None:
return dp[zero_count][one_count][n]
# Initialize variables to store different results
res1, res2, res3 = 0, 0, 0
# Iterate over three possible characters: 0, 1, and 2
for i in range(3):
# Check if we can add '0' to the string (zero_count < K1)
if zero_count < K1 and i == 0:
res1 = count_valid_string(zero_count + 1, 0, K1, K2, n - 1)
# Check if we can add '1' to the string (one_count < K2)
if one_count < K2 and i == 1:
res2 = count_valid_string(zero_count, one_count + 1, K1, K2, n - 1)
# Add '2' to the string
res3 = count_valid_string(zero_count, 0, K1, K2, n - 1)
# Store the result in the memoization table and return the sum modulo 'mod'
dp[zero_count][one_count][n] = (res1 + res2 + res3) % mod
return dp[zero_count][one_count][n]
# Drivers code
def main():
n, K1, K2 = 1012, 3, 5
# Initialize the memoization table with None
for i in range(10):
for j in range(10):
dp[i][j] = [None] * 100005
# Call the function to calculate the valid strings
print(count_valid_string(0, 0, K1, K2, n))
if __name__ == "__main__":
main()
#this code is contributed by Aman.
Time Complexity: O(N)
Auxiliary Space: O(N*K1*K2)
Similar Reads
Count strings with consecutive 1's
Given a number n, count number of n length strings with consecutive 1's in them.Examples: Input : n = 2Output : 1There are 4 strings of length 2, thestrings are 00, 01, 10 and 11. Only the string 11 has consecutive 1's.Input : n = 3Output : 3There are 8 strings of length 3, thestrings are 000, 001,
8 min read
Count of substrings in a Binary String that contains more 1s than 0s
Given a binary string s, the task is to calculate the number of such substrings where the count of 1's is strictly greater than the count of 0's. Examples Input: S = "110011"Output: 11Explanation: Substrings in which the count of 1's is strictly greater than the count of 0's are { S[0]}, {S[0], S[1]
15+ min read
Count valid Bitwise operation combinations for Binary Strings
Given an odd integer N (N >= 3), a binary string S of length N and another string O of length (N-1)/2. Here, each character in string O can be one of the following: '&', '|' or '^' representing Bitwise operations AND, OR, and XOR respectively, the task is to find the number of possible combin
8 min read
Count of sub-strings with equal consecutive 0's and 1's
Given binary string str of 0's and 1's only. The task is to count the total number of substrings of string str such that each substring has an equal number of consecutive 0's and 1's in it. Examples: Input: str = "010011" Output: 4 Explanation: The substrings with consecutive 0's and 1's are "01", "
9 min read
Counting Good Substrings with 0s, 1s, and ?s
Given a string S consisting of characters 0,1,? A string is called good if all the adjacent characters in it are different i.e. of the form 0101010... or 1010101... You can replace ? with 0 or 1. Your task is to determine the number of good contiguous substrings of the string S. Constraint: |S|<2
7 min read
Count of strings that can be formed using a, b and c under given constraints
Given a length n, count the number of strings of length n that can be made using 'a', 'b' and 'c' with at most one 'b' and two 'c's allowed. Examples : Input : n = 3 Output : 19 Below strings follow given constraints: aaa aab aac aba abc aca acb acc baa bac bca bcc caa cab cac cba cbc cca ccb Input
14 min read
Count Substrings with equal number of 0s, 1s and 2s
Given a string that consists of only 0s, 1s and 2s, count the number of substrings that have an equal number of 0s, 1s, and 2s.Examples: Input: str = â0102010âOutput: 2Explanation: Substring str[2, 4] = â102â and substring str[4, 6] = â201â has equal number of 0, 1 and 2Input: str = "102100211"Outpu
9 min read
Count number of binary strings without consecutive 1's
Given a positive integer n, the task is to count all possible distinct binary strings of length n such that there are no consecutive 1's.Examples: Input: n = 3Output: 5Explanation: 5 strings are ("000", "001", "010", "100", "101").Input: n = 2Output: 3Explanation: 3 strings are ("00", "01", "10").Ta
15+ min read
Count ways to generate Binary String not containing "0100" Substring
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 = 4Output: 15Explanation:
15+ min read
Count of substrings of a Binary string containing only 1s
Given a binary string of length N, we need to find out how many substrings of this string contain only 1s. Examples: Input: S = "0110111"Output: 9Explanation:There are 9 substring with only 1's characters. "1" comes 5 times. "11" comes 3 times. "111" comes 1 time. Input: S = "000"Output: 0 The_Appro
6 min read