
Solution
- Use a map to track pattern character -> substring.
- the mapping is bi-direction, so we need to check. Use a set to ensure no substring is reused for a different pattern character.
- At each recursion level:
- If the character is already mapped, check if the next part of the string matches.
- If it's not mapped yet, try every possible substring starting at the current index as a candidate.
class Solution {
public boolean wordPatternMatch(String pattern, String s) {
Map<Character, String> map = new HashMap<>();
Set<String> strMatched = new HashSet<>();
return backtrack(pattern, 0, s, 0, map, strMatched);
}
public boolean backtrack(String pattern, int pIdx, String s, int sIdx,
Map<Character, String> map, Set<String> strMatched) {
if (pIdx == pattern.length()) {
return sIdx == s.length();
}
char c = pattern.charAt(pIdx);
if (map.containsKey(c)) {
String str = map.get(c);
if (!s.startsWith(str, sIdx)) {
return false;
}
return backtrack(pattern, pIdx + 1, s, sIdx + str.length(), map, strMatched);
}
for (int i = sIdx; i < s.length(); i++) {
String newSubstr = s.substring(sIdx, i + 1);
if (strMatched.contains(newSubstr)) {
continue;
}
map.put(c, newSubstr);
strMatched.add(newSubstr);
if (backtrack(pattern, pIdx + 1, s, i + 1, map, strMatched)) {
return true;
}
strMatched.remove(newSubstr);
map.remove(c);
}
return false;
}
}