字典树(Trie树相关)
208. Implement Trie (Prefix Tree)
Implement a trie with insert
, search
, and startsWith
methods. (Medium)
Note:
You may assume that all inputs are consist of lowercase letters a-z
.
分析:
字典树即前缀匹配树,在空间不是很影响的情况下一般采用如下数据结构存储Trie节点
1 class TrieNode { 2 public: 3 // Initialize your data structure here. 4 bool isWord; 5 TrieNode* child[26]; 6 TrieNode(): isWord(false){ 7 memset(child, NULL, sizeof(child)); 8 } 9 };
所以插入、查找等操作比较直观,直接见程序。
代码:
1 class TrieNode { 2 public: 3 // Initialize your data structure here. 4 bool isWord; 5 TrieNode* child[26]; 6 TrieNode(): isWord(false){ 7 memset(child, NULL, sizeof(child)); 8 } 9 }; 10 11 class Trie { 12 public: 13 Trie() { 14 root = new TrieNode(); 15 } 16 17 // Inserts a word into the trie. 18 void insert(string word) { 19 TrieNode* r = root; 20 for (int i = 0; i < word.size(); ++i) { 21 if (r -> child[word[i] - 'a'] == NULL) { 22 r -> child[word[i] - 'a'] = new TrieNode(); 23 24 } 25 r = r -> child[word[i] - 'a']; 26 } 27 r -> isWord = true; 28 } 29 30 // Returns if the word is in the trie. 31 bool search(string word) { 32 TrieNode* r = root; 33 for (int i = 0; i < word.size(); ++i) { 34 if (r -> child[word[i] - 'a'] == NULL) { 35 return false; 36 37 } 38 r = r -> child[word[i] - 'a']; 39 } 40 if (r -> isWord) { 41 return true; 42 } 43 return false; 44 } 45 46 // Returns if there is any word in the trie 47 // that starts with the given prefix. 48 bool startsWith(string prefix) { 49 TrieNode* r = root; 50 for (int i = 0; i < prefix.size(); ++i) { 51 if (r -> child[prefix[i] - 'a'] == NULL) { 52 return false; 53 54 } 55 r = r -> child[prefix[i] - 'a']; 56 } 57 return true; 58 } 59 60 private: 61 TrieNode* root; 62 }; 63 64 // Your Trie object will be instantiated and called as such: 65 // Trie trie; 66 // trie.insert("somestring"); 67 // trie.search("key");
211. Add and Search Word - Data structure design
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. (Medium)
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
.
分析:
继续沿用字典树的思路,只不过加入了“.”通配符,所以在查找过程中加入DFS即可,用辅助函数helper
代码:
1 class TrieNode { 2 public: 3 // Initialize your data structure here. 4 bool isWord; 5 TrieNode* child[26]; 6 TrieNode(): isWord(false){ 7 memset(child, NULL, sizeof(child)); 8 } 9 }; 10 11 class Trie { 12 public: 13 Trie() { 14 root = new TrieNode(); 15 } 16 17 // Inserts a word into the trie. 18 void insert(string word) { 19 TrieNode* r = root; 20 for (int i = 0; i < word.size(); ++i) { 21 if (r -> child[word[i] - 'a'] == NULL) { 22 r -> child[word[i] - 'a'] = new TrieNode(); 23 24 } 25 r = r -> child[word[i] - 'a']; 26 } 27 r -> isWord = true; 28 } 29 30 //helper function for search, use to solve "." problem 31 bool helper(string word, int pos, TrieNode* curRoot) { 32 if (pos == word.size() && curRoot -> isWord) { 33 return true; 34 } 35 if (word[pos] != '.') { 36 if (curRoot -> child[word[pos] - 'a'] == NULL) { 37 return false; 38 } 39 else { 40 return helper(word, pos + 1, curRoot -> child[word[pos] - 'a']); 41 } 42 } 43 else { 44 bool flag = false; 45 for (int i = 0; i < 26; ++i) { 46 if (curRoot -> child[i] != NULL && helper(word, pos + 1, curRoot -> child[i]) ) { 47 flag = true; 48 } 49 } 50 return flag; 51 } 52 return true; 53 } 54 // Returns if the word is in the trie. 55 bool search(string word) { 56 return helper(word, 0, root); 57 } 58 59 private: 60 TrieNode* root; 61 }; 62 63 class WordDictionary { 64 public: 65 Trie dic; 66 // Adds a word into the data structure. 67 void addWord(string word) { 68 dic.insert(word); 69 } 70 71 // Returns if the word is in the data structure. A word could 72 // contain the dot character '.' to represent any one letter. 73 bool search(string word) { 74 return dic.search(word); 75 } 76 }; 77 78 // Your WordDictionary object will be instantiated and called as such: 79 // WordDictionary wordDictionary; 80 // wordDictionary.addWord("word"); 81 // wordDictionary.search("pattern");