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
.
1 public class WordDictionary { 2 public class TrieNode 3 { 4 public Dictionary<char, TrieNode> children = new Dictionary<char, TrieNode>(); 5 public bool isWord = false; 6 } 7 8 private TrieNode root = new TrieNode(); 9 10 /** Initialize your data structure here. */ 11 public WordDictionary() { 12 } 13 14 /** Adds a word into the data structure. */ 15 public void AddWord(string word) { 16 var node = root; 17 18 for (int i = 0; i < word.Length; i++) 19 { 20 if (!node.children.ContainsKey(word[i])) 21 { 22 node.children[word[i]] = new TrieNode(); 23 } 24 25 node = node.children[word[i]]; 26 } 27 28 node.isWord = true; 29 } 30 31 /** Returns if the word is in the data structure. A word could contain the dot character ‘.‘ to represent any one letter. */ 32 public bool Search(string word) { 33 return InternalSearch(word, root); 34 } 35 36 private bool InternalSearch(string word, TrieNode node) { 37 for (int i = 0; i < word.Length; i++) 38 { 39 if (word[i] == ‘.‘) 40 { 41 foreach (var c in node.children.Values) 42 { 43 if (InternalSearch(word.Substring(i + 1, word.Length - i - 1), c)) 44 { 45 return true; 46 } 47 } 48 49 return false; 50 } 51 else if (node.children.ContainsKey(word[i])) 52 { 53 node = node.children[word[i]]; 54 } 55 else 56 { 57 return false; 58 } 59 } 60 61 return node.isWord; 62 } 63 } 64 65 /** 66 * Your WordDictionary object will be instantiated and called as such: 67 * WordDictionary obj = new WordDictionary(); 68 * obj.AddWord(word); 69 * bool param_2 = obj.Search(word); 70 */