Welcome to Subscribe On Youtube
2930. Number of Strings Which Can Be Rearranged to Contain Substring
Description
You are given an integer n
.
A string s
is called good if it contains only lowercase English characters and it is possible to rearrange the characters of s
such that the new string contains "leet"
as a substring.
For example:
- The string
"lteer"
is good because we can rearrange it to form"leetr"
. "letl"
is not good because we cannot rearrange it to contain"leet"
as a substring.
Return the total number of good strings of length n
.
Since the answer may be large, return it modulo 109 + 7
.
A substring is a contiguous sequence of characters within a string.
Example 1:
Input: n = 4 Output: 12 Explanation: The 12 strings which can be rearranged to have "leet" as a substring are: "eelt", "eetl", "elet", "elte", "etel", "etle", "leet", "lete", "ltee", "teel", "tele", and "tlee".
Example 2:
Input: n = 10 Output: 83943898 Explanation: The number of strings with length 10 which can be rearranged to have "leet" as a substring is 526083947580. Hence the answer is 526083947580 % (109 + 7) = 83943898.
Constraints:
1 <= n <= 105
Solutions
Solution 1: Memorization Search
We design a function
The execution logic of the function
If
Otherwise, we can consider adding any lowercase letter other than ‘l’, ‘e’, ‘t’ at the current position, there are 23 in total, so the number of schemes obtained at this time is
We can also consider adding ‘l’ at the current position, and the number of schemes obtained at this time is
To avoid repeated calculations, we can use memorization search.
The time complexity is
Solution 2: Reverse Thinking + Inclusion-Exclusion Principle
We can consider reverse thinking, that is, calculate the number of strings that do not contain the substring “leet”, and then subtract this number from the total.
We divide it into the following cases:
- Case
: represents the number of schemes where the string does not contain the character ‘l’, so we havea .a=25n - Case
: similar tob , represents the number of schemes where the string does not contain the character ‘t’, so we havea .b=25n - Case
: represents the number of schemes where the string does not contain the character ‘e’ or only contains one character ‘e’, so we havec .c=25n+n×25n−1 - Case
: represents the number of schemes where the string does not contain the characters ‘l’ and ‘t’, so we haveab .ab=24n - Case
: represents the number of schemes where the string does not contain the characters ‘l’ and ‘e’ or only contains one character ‘e’, so we haveac .ac=24n+n×24n−1 - Case
: similar tobc , represents the number of schemes where the string does not contain the characters ‘t’ and ‘e’ or only contains one character ‘e’, so we haveac .bc=24n+n×24n−1 - Case
: represents the number of schemes where the string does not contain the characters ‘l’, ‘t’ and ‘e’ or only contains one character ‘e’, so we haveabc .abc=23n+n×23n−1
Then according to the inclusion-exclusion principle,
The total number
The time complexity is
-
class Solution { private final int mod = (int) 1e9 + 7; private Long[][][][] f; public int stringCount(int n) { f = new Long[n + 1][2][3][2]; return (int) dfs(n, 0, 0, 0); } private long dfs(int i, int l, int e, int t) { if (i == 0) { return l == 1 && e == 2 && t == 1 ? 1 : 0; } if (f[i][l][e][t] != null) { return f[i][l][e][t]; } long a = dfs(i - 1, l, e, t) * 23 % mod; long b = dfs(i - 1, Math.min(1, l + 1), e, t); long c = dfs(i - 1, l, Math.min(2, e + 1), t); long d = dfs(i - 1, l, e, Math.min(1, t + 1)); return f[i][l][e][t] = (a + b + c + d) % mod; } }
-
class Solution { public: int stringCount(int n) { const int mod = 1e9 + 7; using ll = long long; ll f[n + 1][2][3][2]; memset(f, -1, sizeof(f)); function<ll(int, int, int, int)> dfs = [&](int i, int l, int e, int t) -> ll { if (i == 0) { return l == 1 && e == 2 && t == 1 ? 1 : 0; } if (f[i][l][e][t] != -1) { return f[i][l][e][t]; } ll a = dfs(i - 1, l, e, t) * 23 % mod; ll b = dfs(i - 1, min(1, l + 1), e, t) % mod; ll c = dfs(i - 1, l, min(2, e + 1), t) % mod; ll d = dfs(i - 1, l, e, min(1, t + 1)) % mod; return f[i][l][e][t] = (a + b + c + d) % mod; }; return dfs(n, 0, 0, 0); } };
-
class Solution: def stringCount(self, n: int) -> int: @cache def dfs(i: int, l: int, e: int, t: int) -> int: if i == 0: return int(l == 1 and e == 2 and t == 1) a = dfs(i - 1, l, e, t) * 23 % mod b = dfs(i - 1, min(1, l + 1), e, t) c = dfs(i - 1, l, min(2, e + 1), t) d = dfs(i - 1, l, e, min(1, t + 1)) return (a + b + c + d) % mod mod = 10**9 + 7 return dfs(n, 0, 0, 0)
-
func stringCount(n int) int { const mod int = 1e9 + 7 f := make([][2][3][2]int, n+1) for i := range f { for j := range f[i] { for k := range f[i][j] { for l := range f[i][j][k] { f[i][j][k][l] = -1 } } } } var dfs func(i, l, e, t int) int dfs = func(i, l, e, t int) int { if i == 0 { if l == 1 && e == 2 && t == 1 { return 1 } return 0 } if f[i][l][e][t] == -1 { a := dfs(i-1, l, e, t) * 23 % mod b := dfs(i-1, min(1, l+1), e, t) c := dfs(i-1, l, min(2, e+1), t) d := dfs(i-1, l, e, min(1, t+1)) f[i][l][e][t] = (a + b + c + d) % mod } return f[i][l][e][t] } return dfs(n, 0, 0, 0) }
-
function stringCount(n: number): number { const mod = 10 ** 9 + 7; const f: number[][][][] = Array.from({ length: n + 1 }, () => Array.from({ length: 2 }, () => Array.from({ length: 3 }, () => Array.from({ length: 2 }, () => -1)), ), ); const dfs = (i: number, l: number, e: number, t: number): number => { if (i === 0) { return l === 1 && e === 2 && t === 1 ? 1 : 0; } if (f[i][l][e][t] !== -1) { return f[i][l][e][t]; } const a = (dfs(i - 1, l, e, t) * 23) % mod; const b = dfs(i - 1, Math.min(1, l + 1), e, t); const c = dfs(i - 1, l, Math.min(2, e + 1), t); const d = dfs(i - 1, l, e, Math.min(1, t + 1)); return (f[i][l][e][t] = (a + b + c + d) % mod); }; return dfs(n, 0, 0, 0); }