-
题目:
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。 实现词典类 WordDictionary : WordDictionary() 初始化词典对象 void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配 bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
-
示例:
输入: ["WordDictionary","addWord","addWord","addWord","search","search","search","search"] [[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]] 输出: [null,null,null,null,false,true,true,true] 解释: WordDictionary wordDictionary = new WordDictionary(); wordDictionary.addWord("bad"); wordDictionary.addWord("dad"); wordDictionary.addWord("mad"); wordDictionary.search("pad"); // return False wordDictionary.search("bad"); // return True wordDictionary.search(".ad"); // return True wordDictionary.search("b.."); // return True
-
提示
1 <= word.length <= 500
addWord
中的word
由小写英文字母组成search
中的word
由 ‘.’ 或小写英文字母组成- 最多调用
50000
次addWord
和search
思路 :
- 使用前缀树存储,再使用深度优先搜索查询。前缀树实现 208 实现 Trie (前缀树)
示例一:
class WordDictionary {
private Trie root;
public WordDictionary() {
root = new Trie();
}
// 插入可以直接使用前缀树的方法
public void addWord(String word) {
root.insert(word);
}
public boolean search(String word) {
return dfs(word, 0, root);
}
/**
* 深搜查询
* @param word 要查找的单词
* @param index 查到第几个字符
* @param node 查找的树
* @return 是否存在
*/
private boolean dfs(String word, int index, Trie node) {
// 查找完成,存在该单词
if (word.length() == index) {
return node.isEnd();
}
Trie[] child = node.getChild();
if (child == null) {
return false;
}
// 如果是 '.' 则查询所有的子节点
if (word.charAt(index) == '.') {
for (int i = 0; i < child.length; i++) {
// 递归查询下一个字符
if (child[i] != null && dfs(word, index + 1, child[i])) {
return true;
}
}
} else {
int i = word.charAt(index) - 'a';
// 非'.' 且查询的字符存在,递归查询下一个字符
if (child[i] != null && dfs(word, index + 1, child[i])) {
return true;
}
}
return false;
}
}
class Trie {
private Trie[] child;
private boolean isEnd;
public Trie() {
child = new Trie[26];
}
public void insert(String word) {
char[] chars = word.toCharArray();
Trie node = this;
for (char c : chars) {
int index = c - 'a';
if (node.child[index] == null) {
node.child[index] = new Trie();
}
node = node.child[index];
}
node.isEnd = true;
}
public boolean search(String word) {
Trie node = searchPrefix(word);
return node != null && node.isEnd;
}
public boolean startsWith(String prefix) {
return searchPrefix(prefix) != null;
}
public Trie searchPrefix(String prefix) {
Trie node = this;
char[] chars = prefix.toCharArray();
for (char c : chars) {
int index = c - 'a';
if (node.child[index] == null) {
return null;
}
node = node.child[index];
}
return node;
}
public Trie[] getChild() {
return child;
}
public boolean isEnd() {
return isEnd;
}
}