内容来自刘宇波老师算法与数据结构体系课
1、Trie 的结构

2、实现 Trie
| |
| |
| |
| |
| public class Trie { |
| |
| private class Node { |
| public boolean isWord; |
| public TreeMap<Character, Node> next; |
| |
| public Node(boolean isWord) { |
| this.isWord = isWord; |
| this.next = new TreeMap<>(); |
| } |
| |
| public Node() { |
| this(false); |
| } |
| } |
| |
| private final Node root; |
| private int size; |
| |
| public Trie() { |
| root = new Node(); |
| size = 0; |
| } |
| |
| public int getSize() { |
| return size; |
| } |
| |
| |
| |
| |
| public void add(String word) { |
| Node cur = root; |
| |
| for (int i = 0; i < word.length(); i++) { |
| char c = word.charAt(i); |
| if (!cur.next.containsKey(c)) cur.next.put(c, new Node()); |
| cur = cur.next.get(c); |
| } |
| |
| if (!cur.isWord) { |
| cur.isWord = true; |
| size++; |
| } |
| } |
| |
| |
| |
| |
| public boolean contains(String word) { |
| Node cur = root; |
| |
| for (int i = 0; i < word.length(); i++) { |
| char c = word.charAt(i); |
| if (!cur.next.containsKey(c)) return false; |
| cur = cur.next.get(c); |
| } |
| |
| return cur.isWord; |
| } |
| |
| |
| |
| |
| public boolean isPrefix(String prefix) { |
| Node cur = root; |
| |
| for (int i = 0; i < prefix.length(); i++) { |
| char c = prefix.charAt(i); |
| if (!cur.next.containsKey(c)) return false; |
| cur = cur.next.get(c); |
| } |
| |
| return true; |
| } |
| } |
3、添加与搜索单词 - 数据结构设计
211 - 添加与搜索单词 - 数据结构设计
| |
| |
| |
| public class WordDictionary { |
| |
| private static class Node { |
| public boolean isWord; |
| public TreeMap<Character, Node> next; |
| |
| public Node(boolean isWord) { |
| this.isWord = isWord; |
| this.next = new TreeMap<>(); |
| } |
| |
| public Node() { |
| this(false); |
| } |
| } |
| |
| private final Node root; |
| |
| public WordDictionary() { |
| root = new Node(); |
| } |
| |
| public void addWord(String word) { |
| Node cur = root; |
| |
| for (int i = 0; i < word.length(); i++) { |
| char c = word.charAt(i); |
| if (!cur.next.containsKey(c)) cur.next.put(c, new Node()); |
| cur = cur.next.get(c); |
| } |
| |
| if (!cur.isWord) cur.isWord = true; |
| } |
| |
| public boolean search(String word) { |
| return match(root, word, 0); |
| } |
| |
| |
| |
| |
| |
| private boolean match(Node node, String word, int index) { |
| if (index == word.length()) return node.isWord; |
| |
| char c = word.charAt(index); |
| |
| if (c != '.') { |
| if (!node.next.containsKey(c)) return false; |
| return match(node.next.get(c), word, index + 1); |
| } else { |
| for (Node nextNode : node.next.values()) { |
| if (match(nextNode, word, index + 1)) return true; |
| } |
| return false; |
| } |
| } |
| } |
4、键值映射
677 - 键值映射
| public class MapSum { |
| |
| private static class Node { |
| public int val; |
| public TreeMap<Character, Node> next; |
| |
| public Node(int val) { |
| this.val = val; |
| next = new TreeMap<>(); |
| } |
| |
| public Node() { |
| this(0); |
| } |
| } |
| |
| private final Node root; |
| |
| public MapSum() { |
| root = new Node(); |
| } |
| |
| public void insert(String word, int val) { |
| Node cur = root; |
| |
| for (int i = 0; i < word.length(); i++) { |
| char c = word.charAt(i); |
| if (!cur.next.containsKey(c)) cur.next.put(c, new Node()); |
| cur = cur.next.get(c); |
| } |
| |
| cur.val = val; |
| } |
| |
| public int sum(String prefix) { |
| Node cur = root; |
| |
| for (int i = 0; i < prefix.length(); i++) { |
| char c = prefix.charAt(i); |
| if (!cur.next.containsKey(c)) return 0; |
| cur = cur.next.get(c); |
| } |
| |
| return sum(cur); |
| } |
| |
| private int sum(Node node) { |
| int sum = node.val; |
| if (node.next.isEmpty()) return sum; |
| |
| for (Node nextNode : node.next.values()) sum += sum(nextNode); |
| return sum; |
| } |
| } |
5、更多话题
Trie 的局限性:空间消耗大
字符串模式识别:后缀树
更多字符串问题:子串查询、文件压缩、模式匹配(正则表达式)、编译原理、DNA
子串查询:Rabin - Karp、KMP、Boyer - Moore
5.1、删除操作

5.2、压缩字典树

5.3、Ternary Search Trie

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步