Leet热题100--208. 实现 Trie (前缀树)--中等

题目

Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。

请你实现 Trie 类:

  • Trie() 初始化前缀树对象。
  • void insert(String word) 向前缀树中插入字符串 word 。
  • boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
  • boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。

示例:

输入

"Trie", "insert", "search", "search", "startsWith", "insert", "search"

\[\], \["apple"\], \["apple"\], \["app"\], \["app"\], \["app"\], \["app"\]

输出

null, null, true, false, true, null, true

解释

Trie trie = new Trie();

trie.insert("apple");

trie.search("apple"); // 返回 True

trie.search("app"); // 返回 False

trie.startsWith("app"); // 返回 True

trie.insert("app");

trie.search("app"); // 返回 True

题解

java 复制代码
class Trie {
    private static class Node {
        Node[] son = new Node[26];
        boolean end = false;
    }

    private final Node root = new Node();

    public void insert(String word) {
        Node cur = root;
        for (char c : word.toCharArray()) {
            c -= 'a';
            if (cur.son[c] == null) { // 无路可走?
                cur.son[c] = new Node(); // new 出来!
            }
            cur = cur.son[c];
        }
        cur.end = true;
    }

    public boolean search(String word) {
        return find(word) == 2;
    }

    public boolean startsWith(String prefix) {
        return find(prefix) != 0;
    }

    private int find(String word) {
        Node cur = root;
        for (char c : word.toCharArray()) {
            c -= 'a';
            if (cur.son[c] == null) { // 道不同,不相为谋
                return 0;
            }
            cur = cur.son[c];
        }
        // 走过同样的路(2=完全匹配,1=前缀匹配)
        return cur.end ? 2 : 1;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

解析

出自:灵茶山艾府:从二叉树到二十六叉树(Python/Java/C++/C/Go/JS/Rust)

  1. private static class Node {Node[] son = new Node[26]; boolean end = false;}: 定义了一个内部类 Node,它是 Trie 的节点结构。son 是一个数组,存储了该节点的子节点;end 用于标识一个单词在此处结束(即该路径在单词字典中形成了一个完整的单词)。
  2. private final Node root = new Node();: 创建根节点,并初始化为一个新的 Node 对象。这个根节点的所有子节点都将作为 Trie 树的起始位置。
  3. 3-5: insert 方法用于向 Trie 中插入字符串 word。它通过遍历 word 中的每个字符来工作,如果当前字符对应的 son 数组索引为 null,就创建一个新的 Node(即初始化该子节点)。最后将单词标记为结束。
  4. 6-8: search 方法用于在 Trie 中查找给定的字符串 word。如果 find 返回的结果是表示完全匹配且该路径结束的 2,则返回 true;否则返回 false。
  5. 9-10: startsWith 方法用于检查是否有任何单词以给定前缀 prefix 开头。如果 find 返回的结果不是表示没有对应字符的路径(即对应索引在 son 数组中不为空),则返回 true;否则返回 false。
  6. 11-20: find 方法用于找出给定的 word。它遍历 word 中的每个字符并尝试从根节点沿着路径向下移动到子树,直到达到单词的末尾或遇到不存在于 Trie 中的字符。如果单词在这个位置结束(end = true)并且找到了对应索引在 son 数组中的节点,返回2;否则表示没有完全匹配且该路径的前缀在此处终止,返回1。
  7. /**
    Your Trie object will be instantiated and called as such:
    Trie obj = new Trie();
    obj.insert(word);
    boolean param_2 = obj.search(word);
    boolean param_3 = obj.startsWith(prefix);
    */
    等价代码用于创建一个新的 Trie,插入单词、搜索单词和检查是否存在以某个前缀开头的单词。实例化的 Trie 对象用于执行这些操作。这个类主要用于快速查找、删除和插入数据结构。
相关推荐
拾荒的小海螺2 小时前
C#:OpenCvSharp 实现图像处理的技术指南
开发语言·图像处理·c#
拿破轮2 小时前
不小心在idea中点了add 到版本控制 怎么样恢复?
java·ide·intellij-idea
自由随风飘7 小时前
python 题目练习1~5
开发语言·python
cynicme8 小时前
力扣3318——计算子数组的 x-sum I(偷懒版)
java·算法·leetcode
Bony-8 小时前
Go语言完全学习指南 - 从基础到精通------语言基础篇
服务器·开发语言·golang
青云交9 小时前
Java 大视界 -- Java 大数据在智能教育学习效果评估与教学质量改进实战
java·实时分析·生成式 ai·个性化教学·智能教育·学习效果评估·教学质量改进
崎岖Qiu9 小时前
【设计模式笔记17】:单例模式1-模式分析
java·笔记·单例模式·设计模式
fl1768319 小时前
基于python的天气预报系统设计和可视化数据分析源码+报告
开发语言·python·数据分析
Lei活在当下9 小时前
【现代 Android APP 架构】09. 聊一聊依赖注入在 Android 开发中的应用
java·架构·android jetpack