字典树(前缀树):
字典树(Trie树)又称前缀树,是一种树形结构,用于高效地存储和检索字符串数据集中的键。 字典树是一种哈希树的变种,其核心思想是利用字符串的公共前缀来减少查询时间,从而最大限度地减少无谓的字符串比较。
1.通过数组实现字典树
数据结构:
int N;//需要放入字典树中的字母的个数,需要我们估计太大了会浪费空间,太小会导致溢出
int[][] trie = new int[N][26];//字典树 tire[i][j]=k:代表第i个放入的字母(j+'a')与第k个字母间存在一条边
int[] sign = new int[N];//sign[i]=k:代表第i个放入的字母是k个字符串的终结符
int id;//代表当前要放入的是第id个字母
Eg:对于apple与app来说
apple的‘app’与app的‘app’可以复用
public void insert(String str) {
int p = 0;//每个字符串的第一个字母我们固定存入trie[0][]
for(int i = 0; i < str.length(); i++) {
if(tire[p][str.charAt(i) - 'a'] == 0) tire[p][str.charAt(i) - 'a'] = ++id;
p = tire[p][str.charAt(i) - 'a'];
}
}
//判断某个字符串是否存在
public boolean search(String word) {
p = 0;
for (int i = 0; i < word.length(); i++) {
if(trie[p][word.charAt(i) - 'a'] == 0) return false;
p = trie[p][word.charAt(i) - 'a'];
}
if(sign[p] > 0) return true;
return false;
}
//判断某个前缀是否存在
public boolean startsWith(String prefix) {
p = 0;
for (int i = 0; i < prefix.length(); i++) {
if(trie[p][prefix.charAt(i) - 'a'] == 0) return false;
p = trie[p][prefix.charAt(i) - 'a'];
}
return true;
}
2.通过树来构造
数据结构:
class Node{
int isEnd;//这个点是几个字符串的结束点
Node[] next = new Node[26]//代表26个字母
}
Node root;//根节点指向的才是第一个字母
public void insert(String word){
Node cur = root;
for(char c : word.toCharArray()){
if(cur.children[c - 'a'] == null){
cur.children[c - 'a'] = new Node();
}
cur = cur.children[c - 'a'];
}
cur.isEnd++;
}
public boolean search(String word){
Node cur = root;
for(char c : word.toCharArray()){
if(cur == null) return false;
cur = cur.children[c - 'a'];
}
if(cur == null || cur.isEnd == 0) return false;
return true;
}
public boolean startsWith(String prefix){
Node cur = root;
for(char c : prefix.toCharArray()){
if(cur.children[c - 'a'] == null) return false;
cur = cur.children[c - 'a'];
}
return true;
}