字典树要来了解一下吗

131 阅读2分钟

字典树要来了解一下吗

字典树结构

image-20200729130251735

从上面的图中,我们或多或少的可以发现一些好玩的特性。

第一:根节点不包含字符,除根节点外的每一个子节点都包含一个字符。

第二:从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。

第三:每个单词的公共前缀作为一个字符节点保存。

Trie 关键词查找过程:

  1. 每次从根结点开始搜索;
  2. 获取关键词的第一个字符,根据该字符选择对应的子节点,转到该子节点继续检索;
  3. 在相应的子节点上,获取关键词的第二个字符,进一步选择对应的子节点进行检索;
  4. 以此类推,进行迭代过程;
  5. 在某个节点处,关键词的所有字母已被取出,则读取附在该节点上的信息,查找完成。

Trie 的应用

  • 字符串检索:事先将已知的一些字符串(字典)的有关信息保存到 Trie 里,查找另外一些未知字符串是否出现过或者出现频率。
  • 字符串最长公共前缀:Trie 利用多个字符串的公共前缀来节省存储空间,反之,当我们把大量字符串存储到一棵 Trie 上时,我们可以快速得到某些字符串的公共前缀。
  • 排序:Trie 树是一棵多叉树,只要先序遍历整棵树,输出相应的字符串,便是按字典序排序的结果。
  • 作为其他数据结构和算法的辅助结构:如后缀树,AC自动机等。

代码

leetcode p14 最长公共前缀 字典树解法

leetcode-cn.com/problems/lo…

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<>();
	}
}