Problem
Design a data structure that supports the following two operations:
addWord(word)
andsearch(word)
search(word)
can search a literal word or a regular expression string containing only lettersa-z
or.
.A
.
means it can represent any one letter.Notice
You may assume that all words are consist of lowercase letters a-z.
Example
addWord("bad") addWord("dad") addWord("mad") search("pad") // return false search("bad") // return true search(".ad") // return true search("b..") // return true
Solution
Trie Tree
struct Node {
bool isWord;
Node *children[26];
Node() {
isWord = false;
for(int i = 0; i < 26; i++) {
children[i] = NULL;
}
}
};
class WordDictionary {
private:
Node *root;
public:
WordDictionary() {
root = new Node();
}
// Adds a word into the data structure.
void addWord(string word) {
Node *node = root;
for(int i = 0; i < word.size(); i++) {
if (node->children[word[i] - 'a'] == NULL) {
Node *newNode = new Node();
node->children[word[i] - 'a'] = newNode;
}
node = node->children[word[i]-'a'];
}
node->isWord = true;
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
bool search(string word) {
if (word.size() == 0) {
return true;
}
return searchFromNode(word, 0, root);
}
bool searchFromNode(string &word, int startIndex, Node *node) {
if (word.size() == startIndex) {
return node->isWord;
}
if (word[startIndex] == '.') {
for(int i = 0; i < 26; i++) {
if (node->children[i]) {
bool result = searchFromNode(word, startIndex + 1, node->children[i]);
if (result) {
return true;
}
}
}
return false;
} else {
if (node->children[word[startIndex]-'a']) {
return searchFromNode(word, startIndex+1, node->children[word[startIndex]-'a']);
} else {
return false;
}
}
}
};
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary;
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");