Similar Problems
Similar Problems not available
Find All Good Strings - Leetcode Solution
Companies:
LeetCode: Find All Good Strings Leetcode Solution
Difficulty: Hard
Topics: string dynamic-programming
Problem Statement:
A string is called good if it satisfies the following conditions:
It contains only lowercase English letters. Its length is exactly $n$. It does not contain any of the substrings $abc$, $def$, or $ghi$. (i.e., it does not contain $abc$, $def$, or $ghi$ as a substring anywhere within the string). Given an integer $n$, return the number of good strings of length $n$. Since the answer may be large, return it modulo $10^9 + 7$.
Solution:
To solve this problem, we can use dynamic programming. We can define a state $dp[i][j]$ that represents the number of good strings of length $i$ that end with the character $j$ (where $j$ ranges from $a$ to $z$).
To compute the value of $dp[i][j]$, we can consider the last two characters of the string. If these characters form a forbidden substring ($ab$, $bc$, $de$, $ef$, $gh$, or $hi$), then the string cannot be good, and the value of $dp[i][j]$ should be 0. Otherwise, we can append the character $j$ to any good string of length $i-1$ that ends with a character that is not forbidden after appending $j$. Therefore, we can compute the value of $dp[i][j]$ as follows:
$$ dp[i][j]=\sum_{k=0}^{25}[forbidden(j,k)=0]dp[i-1][k] \quad (1) $$
where $forbidden(j,k)$ is a function that takes two characters $j$ and $k$ as input and returns $1$ if the substring formed by concatenating $j$ and $k$ is forbidden and $0$ otherwise. We can define the function $forbidden(j,k)$ as follows:
$$ forbidden(j,k)= \begin{cases} 1 &\text{if }(j,k)\in{(a,b),(b,c),(d,e),(e,f),(g,h),(h,i)}\ 0 &\text{otherwise} \end{cases} $$
Finally, the total number of good strings of length $n$ is the sum of $dp[n][j]$ for all characters $j$ from $a$ to $z$:
$$ \sum_{j=a}^{z}dp[n][j] \quad (2) $$
Now, we can implement the above algorithm using a 2D array to store the values of $dp$ and a nested loop to compute the values iteratively. We also need to initialize the base cases $dp[1][j]=1$ for all characters $j$ from $a$ to $z$, since there is only one string of length 1 that ends with each character.
The time complexity of this algorithm is $O(n)$ per state, and there are $26n$ states in total, so the overall time complexity is $O(n^2)$. The space complexity is also $O(n^2)$.
Here is the Python code for the above algorithm:
class Solution:
def countGoodStrings(self, n: int) -> int:
MOD = 10 ** 9 + 7
dp = [[0] * 26 for _ in range(n + 1)]
for i in range(26):
dp[1][i] = 1
for i in range(2, n + 1):
for j in range(26):
for k in range(26):
if not self.forbidden(chr(97+j), chr(97+k)):
dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD
ans = sum(dp[n]) % MOD
return ans
def forbidden(self, j, k):
return (j, k) in [('a', 'b'), ('b', 'c'), ('d', 'e'), ('e', 'f'), ('g', 'h'), ('h', 'i')]
The function countGoodStrings
takes an integer n
as input and returns the number of good strings of length n
modulo $10^9 + 7$. The function first initializes the array dp
with the base case values and then iteratively computes the values of $dp$ using equation $(1)$. Finally, the function computes the total number of good strings using equation $(2)$ and returns it.
The function forbidden
takes two characters j
and k
as input and returns True
if the substring formed by concatenating j
and k
is forbidden and False
otherwise. The function uses a pre-defined list of forbidden substrings to check whether j
and k
form a forbidden substring.
Find All Good Strings Solution Code
1