字典树中 一个节点的所有子孙都有相同的 前缀 ,也就是这个节点对应的字符串,而根节点对应 空字符串 。
上图所示的字典树包括的单词分别为:
a
abc
bac
bbc
ca
例题:请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary
:
WordDictionary()
初始化词典对象void addWord(word)
将word
添加到数据结构中,之后可以对它进行匹配bool search(word)
如果数据结构中存在字符串与word
匹配,则返回true
;否则,返回false
。word
中可能包含一些'.'
,每个.
都可以表示任何一个字母。
字典树类:
//字典树
class Trie {
private Trie[] children;
private boolean isEnd;
public Trie() {
children = new Trie[26];
isEnd = false;
}
public void insert(String word) {
Trie node=this;
for (int i = 0; i < word.length(); i++) {
char ch=word.charAt(i);
int index=ch-'a';
if(node.children[index]==null){
node.children[index]=new Trie();
}
node=node.children[index];
}
node.isEnd=true;
}
public Trie[] getChildren() {
return children;
}
public boolean isEnd() {
return isEnd;
}
//搜索某个字符串是否在字典树中
public boolean search(String word) {
return dfs(word,0,root);
}
public boolean dfs(String word,int begin,Trie root){
if(begin==word.length())
return root.isEnd();
char ch=word.charAt(begin);
//如果当前字符是字母,则判断当前字符对应的子结点是否存在,如果子结点存在则移动到子结点,继续搜索下一个字符,如果子结点不存在则说明单词不存在,返回false;
//如果当前字符是点号,由于点号可以表示任何字母,因此需要对当前结点的所有非空子结点继续搜索下一个字符。
//重复上述步骤,直到返回 \text{false}false 或搜索完给定单词的最后一个字符。
//如果搜索完给定的单词的最后一个字符,则当搜索到的最后一个结点的 isEnd 为 true 时,给定的单词存在。
//特别地,当搜索到点号时,只要存在一个非空子结点可以搜索到给定的单词,即返回true。
if(ch!='.'){
if(root.getChildren()[ch-'a']==null) return false;
root=root.getChildren()[ch-'a'];
if(dfs(word,begin+1,root)) return true;
}
else{
for(int i = 0;i<26;i++){
Trie child = root.getChildren()[i];
if(child!=null&&dfs(word,begin+1,child)){
return true;
}
}
}
return false;
}
}