class WordDictionary {
vector<string> words;
public:
void addWord(string word) {
words.push_back(word);
}
bool search(string pattern) {
for (const string& w : words) {
if (w.size() != pattern.size()) continue;
bool ok = true;
for (size_t i = 0; i < w.size(); i++) {
if (pattern[i] != '.' && pattern[i] != w[i]) {
ok = false;
break;
}
}
if (ok) return true;
}
return false;
}
};
class WordDictionary {
private List<String> words = new ArrayList<>();
public void addWord(String word) {
words.add(word);
}
public boolean search(String pattern) {
for (String w : words) {
if (w.length() != pattern.length()) continue;
boolean ok = true;
for (int i = 0; i < w.length(); i++) {
if (pattern.charAt(i) != '.' && pattern.charAt(i) != w.charAt(i)) {
ok = false;
break;
}
}
if (ok) return true;
}
return false;
}
}
class WordDictionary:
def __init__(self):
self.words = []
def add_word(self, word):
self.words.append(word)
def search(self, pattern):
for w in self.words:
if len(w) != len(pattern): continue
ok = True
for i in range(len(w)):
if pattern[i] != '.' and pattern[i] != w[i]:
ok = False
break
if ok: return True
return False
class WordDictionary {
private words: string[] = [];
addWord(word: string): void {
this.words.push(word);
}
search(pattern: string): boolean {
for (const w of this.words) {
if (w.length !== pattern.length) continue;
let ok = true;
for (let i = 0; i < w.length; i++) {
if (pattern[i] !== '.' && pattern[i] !== w[i]) {
ok = false;
break;
}
}
if (ok) return true;
}
return false;
}
}
bool matches(const string& w, const string& pattern) {
for (size_t i = 0; i < w.size(); i++) {
if (pattern[i] != '.' && pattern[i] != w[i]) return false;
}
return true;
}
class WordDictionary {
unordered_map<int, vector<string>> byLength;
public:
void addWord(string word) {
vector<string>& bucket = byLength[word.size()];
bucket.push_back(word);
// bucket is a reference, so the map entry is already updated
}
bool search(string pattern) {
static const vector<string> none;
auto it = byLength.find(pattern.size());
const vector<string>& bucket = it == byLength.end() ? none : it->second;
for (const string& w : bucket) {
if (matches(w, pattern)) return true;
}
return false;
}
};
class WordDictionary {
private Map<Integer, List<String>> byLength = new HashMap<>();
public void addWord(String word) {
List<String> bucket = byLength.getOrDefault(word.length(), new ArrayList<>());
bucket.add(word);
byLength.put(word.length(), bucket);
}
public boolean search(String pattern) {
List<String> bucket = byLength.getOrDefault(pattern.length(), new ArrayList<>());
for (String w : bucket) {
if (matches(w, pattern)) return true;
}
return false;
}
private boolean matches(String w, String pattern) {
for (int i = 0; i < w.length(); i++) {
if (pattern.charAt(i) != '.' && pattern.charAt(i) != w.charAt(i)) return false;
}
return true;
}
}
class WordDictionary:
def __init__(self):
self.by_length = {}
def add_word(self, word):
bucket = self.by_length.get(len(word), [])
bucket.append(word)
self.by_length[len(word)] = bucket
def search(self, pattern):
bucket = self.by_length.get(len(pattern), [])
for w in bucket:
if matches(w, pattern): return True
return False
def matches(w, pattern):
for i in range(len(w)):
if pattern[i] != '.' and pattern[i] != w[i]: return False
return True
class WordDictionary {
private byLength = new Map<number, string[]>();
addWord(word: string): void {
const bucket = this.byLength.get(word.length) ?? [];
bucket.push(word);
this.byLength.set(word.length, bucket);
}
search(pattern: string): boolean {
const bucket = this.byLength.get(pattern.length) ?? [];
for (const w of bucket) {
if (matches(w, pattern)) return true;
}
return false;
}
}
function matches(w: string, pattern: string): boolean {
for (let i = 0; i < w.length; i++) {
if (pattern[i] !== '.' && pattern[i] !== w[i]) return false;
}
return true;
}
struct TrieNode {
map<char, TrieNode*> children;
bool isEnd = false;
};
class WordDictionary {
TrieNode* root = new TrieNode();
bool dfs(TrieNode* node, int i, const string& pattern) {
if (i == (int)pattern.size()) return node->isEnd;
char ch = pattern[i];
if (ch == '.') {
for (auto& kv : node->children) {
if (dfs(kv.second, i + 1, pattern)) return true;
}
return false;
}
auto it = node->children.find(ch);
return it != node->children.end() && dfs(it->second, i + 1, pattern);
}
public:
void addWord(string word) {
TrieNode* node = root;
for (char ch : word) {
if (!node->children.count(ch)) node->children[ch] = new TrieNode();
node = node->children[ch];
}
node->isEnd = true;
}
bool search(string pattern) {
return dfs(root, 0, pattern);
}
};
class TrieNode {
Map<Character, TrieNode> children = new HashMap<>();
boolean isEnd = false;
}
class WordDictionary {
private TrieNode root = new TrieNode();
public void addWord(String word) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (!node.children.containsKey(ch)) node.children.put(ch, new TrieNode());
node = node.children.get(ch);
}
node.isEnd = true;
}
public boolean search(String pattern) {
return dfs(root, 0, pattern);
}
private boolean dfs(TrieNode node, int i, String pattern) {
if (i == pattern.length()) return node.isEnd;
char ch = pattern.charAt(i);
if (ch == '.') {
for (TrieNode child : node.children.values()) {
if (dfs(child, i + 1, pattern)) return true;
}
return false;
}
TrieNode next = node.children.get(ch);
return next != null && dfs(next, i + 1, pattern);
}
}
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class WordDictionary:
def __init__(self):
self.root = TrieNode()
def add_word(self, word):
node = self.root
for ch in word:
if ch not in node.children: node.children[ch] = TrieNode()
node = node.children[ch]
node.is_end = True
def search(self, pattern):
def dfs(node, i):
if i == len(pattern): return node.is_end
ch = pattern[i]
if ch == '.':
for child in node.children.values():
if dfs(child, i + 1): return True
return False
nxt = node.children.get(ch)
return nxt is not None and dfs(nxt, i + 1)
return dfs(self.root, 0)
class TrieNode {
children = new Map<string, TrieNode>();
isEnd = false;
}
class WordDictionary {
private root = new TrieNode();
addWord(word: string): void {
let node = this.root;
for (const ch of word) {
if (!node.children.has(ch)) node.children.set(ch, new TrieNode());
node = node.children.get(ch)!;
}
node.isEnd = true;
}
search(pattern: string): boolean {
const dfs = (node: TrieNode, i: number): boolean => {
if (i === pattern.length) return node.isEnd;
const ch = pattern[i];
if (ch === '.') {
for (const child of node.children.values()) {
if (dfs(child, i + 1)) return true;
}
return false;
}
const next = node.children.get(ch);
return next !== undefined && dfs(next, i + 1);
};
return dfs(this.root, 0);
}
}
class WordDictionary {
vector<int> next = vector<int>(26, 0);
vector<bool> end = {false};
int maxLen = 0;
public:
void addWord(string word) {
maxLen = max(maxLen, (int)word.size());
int node = 0;
for (char ch : word) {
int c = ch - 'a';
if (next[node * 26 + c] == 0) {
next[node * 26 + c] = end.size();
end.push_back(false);
next.insert(next.end(), 26, 0);
}
node = next[node * 26 + c];
}
end[node] = true;
}
bool search(string pattern) {
if ((int)pattern.size() > maxLen) return false;
vector<pair<int, int>> stack = {{0, 0}};
while (!stack.empty()) {
auto [node, i] = stack.back(); stack.pop_back();
if (i == (int)pattern.size()) {
if (end[node]) return true;
continue;
}
if (pattern[i] == '.') {
for (int c = 0; c < 26; c++) {
int child = next[node * 26 + c];
if (child != 0) stack.push_back({child, i + 1});
}
} else {
int child = next[node * 26 + (pattern[i] - 'a')];
if (child != 0) stack.push_back({child, i + 1});
}
}
return false;
}
};
class WordDictionary {
private List<Integer> next = new ArrayList<>(Collections.nCopies(26, 0));
private List<Boolean> end = new ArrayList<>(List.of(false));
private int maxLen = 0;
public void addWord(String word) {
maxLen = Math.max(maxLen, word.length());
int node = 0;
for (char ch : word.toCharArray()) {
int c = ch - 'a';
if (next.get(node * 26 + c) == 0) {
next.set(node * 26 + c, end.size());
end.add(false);
next.addAll(Collections.nCopies(26, 0));
}
node = next.get(node * 26 + c);
}
end.set(node, true);
}
public boolean search(String pattern) {
if (pattern.length() > maxLen) return false;
Deque<int[]> stack = new ArrayDeque<>();
stack.push(new int[]{0, 0});
while (!stack.isEmpty()) {
int[] top = stack.pop();
int node = top[0], i = top[1];
if (i == pattern.length()) {
if (end.get(node)) return true;
continue;
}
if (pattern.charAt(i) == '.') {
for (int c = 0; c < 26; c++) {
int child = next.get(node * 26 + c);
if (child != 0) stack.push(new int[]{child, i + 1});
}
} else {
int child = next.get(node * 26 + (pattern.charAt(i) - 'a'));
if (child != 0) stack.push(new int[]{child, i + 1});
}
}
return false;
}
}
class WordDictionary:
def __init__(self):
self.next = [0] * 26
self.end = [False]
self.max_len = 0
def add_word(self, word):
self.max_len = max(self.max_len, len(word))
node = 0
for ch in word:
c = ord(ch) - 97
if self.next[node * 26 + c] == 0:
self.next[node * 26 + c] = len(self.end)
self.end.append(False)
self.next.extend([0] * 26)
node = self.next[node * 26 + c]
self.end[node] = True
def search(self, pattern):
if len(pattern) > self.max_len: return False
stack = [(0, 0)]
while stack:
node, i = stack.pop()
if i == len(pattern):
if self.end[node]: return True
continue
if pattern[i] == '.':
for c in range(26):
child = self.next[node * 26 + c]
if child != 0: stack.append((child, i + 1))
else:
child = self.next[node * 26 + ord(pattern[i]) - 97]
if child != 0: stack.append((child, i + 1))
return False
class WordDictionary {
private next: number[] = new Array(26).fill(0);
private end: boolean[] = [false];
private maxLen = 0;
addWord(word: string): void {
this.maxLen = Math.max(this.maxLen, word.length);
let node = 0;
for (const ch of word) {
const c = ch.charCodeAt(0) - 97;
if (this.next[node * 26 + c] === 0) {
this.next[node * 26 + c] = this.end.length;
this.end.push(false);
this.next.push(...new Array(26).fill(0));
}
node = this.next[node * 26 + c];
}
this.end[node] = true;
}
search(pattern: string): boolean {
if (pattern.length > this.maxLen) return false;
const stack: number[][] = [[0, 0]];
while (stack.length > 0) {
const [node, i] = stack.pop()!;
if (i === pattern.length) {
if (this.end[node]) return true;
continue;
}
if (pattern[i] === '.') {
for (let c = 0; c < 26; c++) {
const child = this.next[node * 26 + c];
if (child !== 0) stack.push([child, i + 1]);
}
} else {
const child = this.next[node * 26 + pattern.charCodeAt(i) - 97];
if (child !== 0) stack.push([child, i + 1]);
}
}
return false;
}
}