与208.前缀树的设计是一样的,关键点在于word中存在通配符“.",所以针对该特殊情况,在search时针对这里进行全子节点的深度搜索
class WordDictionary {TrieNode root;private class TrieNode {char val;// 当前节点的值,冗余了,可不写Map<Character, TrieNode> children;// 当前节点的孩子boolean isEnd;// 标记是否是叶节点,默认为falsepublic TrieNode() {children = new HashMap<>();}}public WordDictionary() {root = new TrieNode();}public void addWord(String word) {TrieNode cur = root;for (int i = 0; i < word.length(); i++) {//不存在该字符则在子节点中创建if (!cur.children.containsKey(word.charAt(i))) {cur.children.put(word.charAt(i), new TrieNode());}//指针向子节点偏移cur = cur.children.get(word.charAt(i));}cur.isEnd = true;//创建到最后一个字符时就是叶节点,置为true}public boolean search(String word) {return search(word, root);}private boolean search(String word, TrieNode root) {TrieNode cur = root;for (int i = 0; i < word.length(); i++) {//1.如果word中当前位置是.那么需要遍历当前节点之后的每条路径if (word.charAt(i) == '.') {Set<Character> children = cur.children.keySet();for (Character child : children) {if (search(word.substring(i + 1), cur.children.get(child))) {return true;}}return false;}//2.如果word中当前位置字符并不存在直接返回falseif (!cur.children.containsKey(word.charAt(i))) {return false;}//3.如果word中当前位置字符匹配,指针向子节点偏移cur = cur.children.get(word.charAt(i));}return cur.isEnd;}
}/*** Your WordDictionary object will be instantiated and called as such:* WordDictionary obj = new WordDictionary();* obj.addWord(word);* boolean param_2 = obj.search(word);*/