Find All Good Strings - Problem

Given the strings s1 and s2 of size n and the string evil, return the number of good strings.

A good string has size n, it is alphabetically greater than or equal to s1, it is alphabetically smaller than or equal to s2, and it does not contain the string evil as a substring.

Since the answer can be a huge number, return this modulo 10⁹ + 7.

Input & Output

Example 1 — Basic Case
$ Input: n = 2, s1 = "aa", s2 = "da", evil = "b"
Output: 51
💡 Note: Valid strings are from "aa" to "da" without containing "b": aa, ac, ad, ..., ca, cc, cd, da. Count excludes any string with 'b'.
Example 2 — Evil Substring Blocking
$ Input: n = 8, s1 = "leetcode", s2 = "leetgoes", evil = "leet"
Output: 0
💡 Note: Since s1 starts with "leet" and evil is "leet", any valid string would contain the evil substring, so result is 0.
Example 3 — No Evil Match
$ Input: n = 2, s1 = "gx", s2 = "gz", evil = "x"
Output: 2
💡 Note: Valid strings in range [gx, gz] without 'x' are: gy, gz. Total count is 2.

Constraints

  • 1 ≤ n ≤ 500
  • 1 ≤ |evil| ≤ 50
  • s1.length == s2.length == n
  • s1 ≤ s2
  • s1, s2, evil consist only of lowercase letters

Visualization

Tap to expand
Find All Good Strings INPUT String Range [s1, s2] "aa" to "da" Evil Substring "b" Parameters n = 2 s1 = "aa" s2 = "da" All 2-char strings from "aa" to "da" without "b" aa, ac, ad, ... da Exclude: ab, ba, bb, bc, bd ALGORITHM STEPS 1 Define DP State dp[pos][tight1][tight2][kmpState] 2 KMP for Evil Match Track partial evil matches 3 Digit DP Bound by s1 and s2 4 Count Valid Strings Exclude strings with evil DP Transition pos=0 pos=1 end tight1: bound by s1 (lower) tight2: bound by s2 (upper) kmpState: evil prefix matched Skip if kmpState == len(evil) FINAL RESULT Good Strings Count 51 Calculation Breakdown Total strings "aa" to "da": 4 x 26 = 104 Strings with "b": 53 Good strings: 104 - 53 = 51 Result modulo 10^9 + 7 51 % 1000000007 = 51 OK Key Insight: Combine Digit DP with KMP pattern matching. Use 4D DP state: position, lower bound flag, upper bound flag, and KMP failure state. Skip any state where evil string is fully matched. Time: O(n * 26 * len(evil)), Space: O(n * len(evil)) with memoization. TutorialsPoint - Find All Good Strings | DP + KMP Approach
Asked in
Google 15 Microsoft 8 Amazon 12
18.5K Views
Medium Frequency
~35 min Avg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen