[
dfs
backtracking
]
Leetcode 0291. Word Pattern II
Problem statement
https://leetcode.com/problems/word-pattern-ii/
Solution
The idea is to use dfs with the following parameters
id_p
is index in patternp
id_s
is index in strings
d_ps
is dictionary of connections in the directionp
$\to$s
d_sp
is dictionary of connections in the directions
$\to$p
Next, we use idea of problem 0290 Word Pattern. We take one symbol from pattern
and check different bijections.
- If this letter was not in
d_ps
, then we try to create new connections, take1, 2, ...
symbols froms
. Make sure that strings[id_s:i+1]
not ind_sp
and then rundfs
recursively: if at least for one option we havetrue
, then returntrue
. - If this letter was already in
d_ps
, then check that we can continue strings
and if we can, and anwer for subproblem istrue
, returntrue
. - If we never returned true, return false in the end.
Complexity
Time complexity can be estimated as $O(n \cdot C^{m-1}{n-1})$, space complexity is $O(m + n)$.
Code
class Solution:
def wordPatternMatch(self, p, s):
m, n = len(p), len(s)
def dfs(id_p, id_s, d_ps, d_sp):
if id_s == n and id_p == m: return True
if id_s == n or id_p == m: return False
new_letter = p[id_p]
if new_letter not in d_ps:
for i in range(id_s, n):
if s[id_s:i+1] not in d_sp:
d_ps[new_letter] = s[id_s:i+1]
d_sp[s[id_s:i+1]] = new_letter
if dfs(id_p + 1, i + 1, d_ps, d_sp): return True
d_ps.pop(new_letter)
d_sp.pop(s[id_s:i+1])
else:
corr = d_ps[new_letter]
if s[id_s:].startswith(corr):
if dfs(id_p + 1, id_s + len(corr), d_ps, d_sp): return True
return False
return dfs(0, 0, {}, {})