@[toc](208. 实现 Trie (前缀树))
题目
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
说明:
- 你可以假设所有的输入都是由小写字母 a-z 构成的。
- 保证所有输入均为非空字符串。
解题思路
我们要构建一个Trie,且题目说所有的输入都是由小写字母 a-z 构成的。所以我们只给给trie的children定义为一个长度为26
的数组就可以了。
再来看一下insert
方法的实现:
首先我们需要遍历要插入的这个单词,将它拆分成一个个的char,在Trie去寻找一个个char是否存在,存在就往下走,不存在就在下标为c-'a'
的位置新建出来该char。最后将isWord=true
。
剩下的两个方法大概思路都和插入差不多,只要看代码的注释就能明白。
代码
class Trie {
class TrieNode{
boolean isWord=false;
TrieNode[] children;
public TrieNode(){
children=new TrieNode[26];//因为本次的输入是26个小写英文字母,所以孩子节点就设置成一个长度为26的数组
}
}
/** Initialize your data structure here. */
TrieNode root;
public Trie() {
root=new TrieNode();//构造出来根节点
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode cur=root;
for(int i =0;i<word.length();i++){
char c=word.charAt(i);//分割出来字符
//c-'a' 得到的是数字, 比如'a'-'a'=0;'b'-'a'=1;
if(cur.children[c-'a']==null){//cur节点的[c-'a']下标处没有东西,证明没有该字符在trie中。
cur.children[c-'a']=new TrieNode();//没有就新建一个
}
//如果有该节点,那么就要走到该节点去。
cur=cur.children[c-'a'];
}
cur.isWord=true; //经过上面的循环整个单词已经插入完成了,所以把isWord置为true
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode cur=root;
for(int i =0;i<word.length();i++){
char c=word.charAt(i);//分割出来字符
//c-'a' 得到的是数字, 比如'a'-'a'=0;'b'-'a'=1;
if(cur.children[c-'a']==null){//cur节点的[c-'a']下标处没有东西,证明没有该字符在trie中。
return false;//搜索到一个字符没有就直接返回false。比如cat,你都搜索到a没有了,就不用往下搜索了
}
//如果有该字符,那么就要走到该节点去。再继续往下搜索
cur=cur.children[c-'a'];
}
return cur.isWord;//有归有,是不是单词还要看它的isWord属性来判定。
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode cur=root;
for(int i =0;i<prefix.length();i++){
char c=prefix.charAt(i);//分割出来字符
//c-'a' 得到的是数字, 比如'a'-'a'=0;'b'-'a'=1;
if(cur.children[c-'a']==null){//cur节点的[c-'a']下标处没有东西,证明没有该字符在trie中。
return false;//搜索到一个字符没有就直接返回false。比如cat,你都搜索到a没有了,就不用往下搜索了
}
//如果有该字符,那么就要走到该节点去。再继续往下搜索
cur=cur.children[c-'a'];
}
return true;//全找到的直接返回true
}
}