Problem:
Design a data structure that supports the following two operations:
void addWord(word) bool search(word)
search(word) can search a literal word or a regular expression string containing only letters a-z
or .
. A .
means it can represent any one letter.
For example:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
Note:
You may assume that all words are consist of lowercase letters a-z
.
Analysis:
Solutions:
C++:
class TrieNode {
public:
// Initialize your data structure here.
TrieNode() {
mp_node.resize(26, NULL);
mb_is_word = false;
}
vector<TrieNode *> mp_node;
bool mb_is_word;
};
class Trie {
public:
Trie() {
root = new TrieNode();
}
TrieNode *GetRoot() { return root; }
private:
TrieNode* root;
};
class WordDictionary {
public:
WordDictionary() {
trie = new Trie();
}
// Adds a word into the data structure.
void addWord(string word) {
TrieNode *p_curr = trie->GetRoot();
for(int i = 0; i < word.size(); ++i) {
if(p_curr->mp_node[word[i] - 'a'] == NULL)
p_curr->mp_node[word[i] - 'a'] = new TrieNode();
p_curr = p_curr->mp_node[word[i] - 'a'];
}
p_curr->mb_is_word = true;
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
bool search_aux(string &word, int pos, TrieNode *p_cur) {
if(pos == word.size()) {
if(p_cur)
return p_cur->mb_is_word;
else
return false;
}
if(word[pos] >= 'a' && word[pos] <= 'z') {
TrieNode *p_next = p_cur->mp_node[word[pos] - 'a'];
if(p_next == NULL)
return false;
return search_aux(word, pos + 1, p_next);
}
if(word[pos] == '.') {
for(int i = 0; i < 26; ++i) {
TrieNode *p_next = p_cur->mp_node[i];
if(p_next && search_aux(word, pos + 1, p_next))
return true;
}
}
return false;
}
bool search(string word) {
return search_aux(word, 0, trie->GetRoot());
}
private:
Trie *trie;
};
Java
:
Python: