实现 Trie (前缀树) - LeetCode 热题 54

本文介绍了如何实现Trie(前缀树)数据结构,包括构造Trie类,实现insert、search和startsWith方法,用于高效存储和检索字符串。通过实例展示了这些操作在LeetCode热题中的应用。
摘要由CSDN通过智能技术生成

大家好!我是曾续缘💜

今天是《LeetCode 热题 100》系列

发车第 54 天

图论第 4 题

❤️点赞 👍 收藏 ⭐再看,养成习惯

实现 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

提示:

  • 1 <= word.length, prefix.length <= 2000
  • wordprefix 仅由小写英文字母组成
  • insertsearchstartsWith 调用次数 总计 不超过 3 * 104
难度:💖💖

解题方法

在这里插入图片描述

Trie树的结构

Trie树的每个节点需要存储27个信息,包括1个终结标志和26个字母。具体实现可以采用一个布尔类型来表示终结标志,并使用一个长度为26的数组来分别对应字母a-z。数组中的每个元素都是一个Trie树节点本身,,体现了递归特性。

我们可以利用布尔类型来表示是否存在终结标志,而数组中某个元素是否为空对象则可以表示对应的字母是否存在。

  • 每个 Trie 节点包含一个长度为 26 的 Trie 数组 children,对应英文字母 a-z。
  • 每个节点还包含一个布尔值 isEnd,表示该节点是否为一个单词的结尾。

插入操作

  1. 从根节点开始遍历要插入的字符串 word 中的每个字符。
  2. 对于每个字符,计算其在 children 数组中的索引(即将字符转换为数组下标)。
  3. 如果当前节点的对应子节点为空,则创建一个新的 Trie 节点并赋值给当前节点的对应子节点。
  4. 将当前节点移动到该子节点。
  5. 最终将最后一个字符所在的节点的 isEnd 置为 true,表示一个单词的结束。

搜索操作

  1. 从根节点开始遍历要搜索的字符串,逐个字符在 children 数组中查找对应的子节点。
  2. 如果遇到某个字符对应的子节点为空,说明 Trie 中不存在该字符串,返回 false
  3. 若搜索完所有字符后,最终节点的 isEndtrue,则说明 Trie 中存在该字符串,返回 true;否则返回 false

前缀匹配操作

  1. 与搜索操作类似,从根节点开始遍历要匹配的前缀字符串。
  2. 如果遇到某个字符对应的子节点为空,说明 Trie 中不存在以该前缀开头的字符串,返回 false
  3. 若成功遍历完前缀字符串,返回 true,表示存在以该前缀开头的字符串,与搜索操作不同的是不需要判断isEnd

Code

class Trie {
    private Trie[] children;
    private boolean isEnd;

    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }
    
    public void insert(String word) {
        Trie cur = this;
        for(int i = 0; i < word.length(); i++){
            char ch = word.charAt(i);
            int index = ch - 'a';
            if(cur.children[index] == null){
                cur.children[index] = new Trie();
            }
            cur = cur.children[index];
        }
        cur.isEnd = true;
    }
    
    public boolean search(String word) {
        Trie cur = this;
        for(int i = 0; i < word.length(); i++){
            char ch = word.charAt(i);
            int index = ch - 'a';
            if(cur.children[index] == null){
                return false;
            }
            cur = cur.children[index];
        }
        return cur.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        Trie cur = this;
        for(int i = 0; i < prefix.length(); i++){
            char ch = prefix.charAt(i);
            int index = ch - 'a';
            if(cur.children[index] == null){
                return false;
            }
            cur = cur.children[index];
        }
        return true;
    }
}

/**
 * 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);
 */
ie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值