- Define precisely what one DP state represents.
- Establish the base cases before transitions are evaluated.
- Process states in dependency order and combine only already-known values.
Code notes
- 58 lines of Python from the credited upstream file 1397.py.
- The implementation visibly relies on sequence storage, cached states.
- No explicit loop blocks detected.
Complexity
Multiply the number of reachable states by the work performed for each transition, then include the stored state table in memory usage.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution:2 def findGoodStrings(self, n: int, s1: str, s2: str, evil: str) -> int:3 MOD = 1_000_000_0074 evilLPS = self._getLPS(evil)5 6 @functools.lru_cache(None)7 def getNextMatchedEvilCount(j: int, currChar: str) -> int:8 """9 Returns the number of next matched evil count, where there're j matches10 with `evil` and the current letter is ('a' + j).11 """12 while j > 0 and evil[j] != currChar:13 j = evilLPS[j - 1]14 return j + 1 if evil[j] == currChar else j15 16 @functools.lru_cache(None)17 def dp(i: int, matchedEvilCount: int, isS1Prefix: bool, isS2Prefix: bool) -> int:18 """19 Returns the number of good strings for s[i..n), where there're j matches20 with `evil`, `isS1Prefix` indicates if the current letter is tightly bound21 for `s1` and `isS2Prefix` indicates if the current letter is tightly bound22 for `s2`.23 """24 25 if matchedEvilCount == len(evil):26 return 027 28 if i == n:29 return 130 ans = 031 minCharIndex = ord(s1[i]) if isS1Prefix else ord('a')32 maxCharIndex = ord(s2[i]) if isS2Prefix else ord('z')33 for charIndex in range(minCharIndex, maxCharIndex + 1):34 c = chr(charIndex)35 nextMatchedEvilCount = getNextMatchedEvilCount(matchedEvilCount, c)36 ans += dp(i + 1, nextMatchedEvilCount,37 isS1Prefix and c == s1[i],38 isS2Prefix and c == s2[i])39 ans %= MOD40 return ans41 42 return dp(0, 0, True, True)43 44 def _getLPS(self, pattern: str) -> list[int]:45 """46 Returns the lps array, where lps[i] is the length of the longest prefix of47 pattern[0..i] which is also a suffix of this substring.48 """49 lps = [0] * len(pattern)50 j = 051 for i in range(1, len(pattern)):52 while j > 0 and pattern[j] != pattern[i]:53 j = lps[j - 1]54 if pattern[i] == pattern[j]:55 lps[i] = j + 156 j += 157 return lps58