字典树要来了解一下吗
字典树结构

从上面的图中,我们或多或少的可以发现一些好玩的特性。
第一:根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
第二:从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。
第三:每个单词的公共前缀作为一个字符节点保存。
Trie 关键词查找过程:
- 每次从根结点开始搜索;
- 获取关键词的第一个字符,根据该字符选择对应的子节点,转到该子节点继续检索;
- 在相应的子节点上,获取关键词的第二个字符,进一步选择对应的子节点进行检索;
- 以此类推,进行迭代过程;
- 在某个节点处,关键词的所有字母已被取出,则读取附在该节点上的信息,查找完成。
Trie 的应用
- 字符串检索:事先将已知的一些字符串(字典)的有关信息保存到 Trie 里,查找另外一些未知字符串是否出现过或者出现频率。
- 字符串最长公共前缀:Trie 利用多个字符串的公共前缀来节省存储空间,反之,当我们把大量字符串存储到一棵 Trie 上时,我们可以快速得到某些字符串的公共前缀。
- 排序:Trie 树是一棵多叉树,只要先序遍历整棵树,输出相应的字符串,便是按字典序排序的结果。
- 作为其他数据结构和算法的辅助结构:如后缀树,AC自动机等。
代码
leetcode p14 最长公共前缀 字典树解法
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0) {
return "";
}
TrieNode root = new TrieNode();
for (String str : strs) {
if(str == null || str.length() == 0) {
return "";
}
add(root,str);
}
TrieNode cur = root;
StringBuilder sb = new StringBuilder();
while (cur.children.keySet().size() == 1 && !cur.isEnd) {
Character character = cur.children.keySet().iterator().next();
sb.append(character);
cur = cur.children.get(character);
}
return sb.toString();
}
public void add(TrieNode root, String s) {
char[] chars = s.toCharArray();
TrieNode cur = root;
for(int i = 0;i < chars.length; i++) {
if(!cur.children.containsKey(chars[i])) {
cur.children.put(chars[i],new TrieNode());
}
cur = cur.children.get(chars[i]);
}
cur.isEnd = true;
}
class TrieNode {
boolean isEnd;
HashMap<Character,TrieNode> children = new HashMap<>();
}
}