Number of Strings Which Can Be Rearranged to Contain Substring
MedPrompt
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
Approaches
2 approaches with complexity analysis and trade-offs.
This approach involves building the strings of length n incrementally while keeping track of the necessary character counts. We define a state based on whether we have seen at least one 'l', at least one 't', and how many 'e's we've seen (0, 1, or 2+).
Algorithm
- Define a DP state
dp[l_flag][e_count][t_flag]to count strings based on the required character counts. - The state parameters are:
l_flag: 0 for no 'l's, 1 for at least one 'l'.e_count: 0, 1, or 2, representing the count of 'e's (capped at 2).t_flag: 0 for no 't's, 1 for at least one 't'.
- Initialize a DP table
dp[2][3][2]withdp[0][0][0] = 1(for the empty string) and all other states as 0. - Iterate from
i = 1tonto build strings of increasing length. - In each iteration, compute a
new_dptable for lengthibased on thedptable for lengthi-1. - The transitions are calculated by considering appending a character ('l', 'e', 't', or one of the 23 others) to the strings of the previous length.
- After
niterations, the answer is the value in the state that meets all conditions, which isdp[1][2][1].
Walkthrough
We use a dynamic programming table, dp[l_flag][e_count][t_flag], to store the number of strings of a certain length that satisfy a specific state. The state is defined by three parameters:
l_flag: 0 if no 'l' has been used, 1 if at least one 'l' has been used.e_count: The number of 'e's used, capped at 2 (i.e., states are 0, 1, or >=2).t_flag: 0 if no 't' has been used, 1 if at least one 't' has been used.
The DP table size is 2 x 3 x 2, which is constant. We can optimize space by only storing the counts for the current length, as the counts for length i only depend on length i-1.
All calculations are performed modulo 10^9 + 7.
class Solution { public int stringCount(int n) { long MOD = 1_000_000_007; if (n < 4) return 0; // dp[l_flag][e_count][t_flag] long[][][] dp = new long[2][3][2]; dp[0][0][0] = 1; // For the empty string for (int i = 0; i < n; i++) { long[][][] newDp = new long[2][3][2]; for (int l = 0; l < 2; l++) { for (int e = 0; e < 3; e++) { for (int t = 0; t < 2; t++) { if (dp[l][e][t] == 0) continue; long ways = dp[l][e][t]; // Case 1: Append 'l' newDp[1][e][t] = (newDp[1][e][t] + ways) % MOD; // Case 2: Append 'e' newDp[l][Math.min(2, e + 1)][t] = (newDp[l][Math.min(2, e + 1)][t] + ways) % MOD; // Case 3: Append 't' newDp[l][e][1] = (newDp[l][e][1] + ways) % MOD; // Case 4: Append any other character (26 - 3 = 23 choices) newDp[l][e][t] = (newDp[l][e][t] + ways * 23) % MOD; } } } dp = newDp; } return (int) dp[1][2][1]; }}Complexity
Time
O(n). The main loop runs `n` times, and inside the loop, we perform a constant number of operations (12 states * 4 transitions).
Space
O(1). We use two DP tables of size `2 * 3 * 2`, which is constant space.
Trade-offs
Pros
More intuitive than combinatorics if you are familiar with DP.
Handles state transitions explicitly and is generally easier to debug.
Cons
Less efficient than the combinatorics approach, with a time complexity linear in
n.
Solutions
Solution
class Solution {private final int mod = (int)1 e9 + 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; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.