Use Trie data structure. For wildcards '.', recursively search all non-null child nodes at current position.
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class WordDictionary:
def __init__(self):
self.root = TrieNode()
def addWord(self, word: str) -> None:
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def search(self, word: str) -> bool:
def dfs(index, node):
if index == len(word):
return node.is_end
char = word[index]
if char == ".":
for child in node.children.values():
if dfs(index + 1, child):
return True
return False
else:
if char not in node.children:
return False
return dfs(index + 1, node.children[char])
return dfs(0, self.root)
class TrieNode {
Map children = new HashMap<>();
boolean isEnd = false;
}
class WordDictionary {
private TrieNode root;
public WordDictionary() {
root = new TrieNode();
}
public void addWord(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
node.children.putIfAbsent(c, new TrieNode());
node = node.children.get(c);
}
node.isEnd = true;
}
public boolean search(String word) {
return dfs(0, root, word);
}
private boolean dfs(int index, TrieNode node, String word) {
if (index == word.length()) return node.isEnd;
char c = word.charAt(index);
if (c == '.') {
for (TrieNode child : node.children.values()) {
if (dfs(index + 1, child, word)) return true;
}
return false;
} else {
if (!node.children.containsKey(c)) return false;
return dfs(index + 1, node.children.get(c), word);
}
}
}