208. 实现 Trie (前缀树)

文章目录

题目

图论: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

提示:

1 <= word.length, prefix.length <= 2000

word 和 prefix 仅由小写英文字母组成

insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次

代码

cpp 复制代码
//定义前缀树的节点
class TrieNode{
public:
    unordered_map<char,TrieNode*>children;
    bool isEnd;
    TrieNode(){
        children.clear();
        isEnd=false;//结尾标志
    }
};
class Trie {
private:
    TrieNode * root;
public:
    Trie() {
        root=new TrieNode();//前缀树根节点为空
    }
    
    void insert(string word) {
        TrieNode* cur=root;
        for(int i=0;i<word.length();i++){
            if(cur->children.count(word[i])==0){//没有当前字母则为该字母创建节点
                cur->children[word[i]]=new TrieNode();
            }
            cur=cur->children[word[i]];//更新当前节点
        }
        cur->isEnd=true;//将最后一个节点设置标志表示最后一个节点
    }
    bool search(string word) {
        TrieNode* cur=root;//根节点
        for(int i=0;i<word.length();i++){
            if(cur->children.count(word[i])==0){//判断当前节点是否存在
                return false;
            }
            cur=cur->children[word[i]];
        }
        return cur->isEnd;//返回最后一个节点的标志为
    }
    bool startsWith(string prefix) {
        TrieNode *cur=root;
        for(int i=0;i<prefix.length();i++){
            if(cur->children.count(prefix[i])==0){//若当前字符的节点不存在直接返回false
                return false;
            }
            cur=cur->children[prefix[i]];
        }
        return true;//判断到最后结束,说明都匹配到了则返回true
    }
};

原理图

原理解释

提示:算法流程及解释在代码中已标注

TrieNode 节点结构:

unordered_map<char, TrieNode*>:存储字符 → 子节点的映射(可能是26个字母)

bool isEnd:标记当前节点是否是一个完整字符串的结尾

构造函数:初始化子节点为空、结尾标记为 false

Trie 构造函数:

创建一个空的根节点

根节点不存储任何字符

整棵树从根节点开始生长

insert (word) 插入字符串算法步骤:

作用:把一个单词加入前缀树

从根节点开始,用指针 cur 指向当前节点,然后遍历单词的每一个字符

检查当前节点的子节点中是否存在该字符,若不存在则创建一个新节点,存入子节点映射,若存在,不做操作。将 cur 移动到该字符对应的子节点重复 2~4,直到单词所有字符遍历完成将最后一个字符所在节点的 isEnd 设为 true,表示单词结束

search (word) 查找完整单词算法步骤:

作用:判断整个单词是否完整存在

从根节点开始,cur 指向当前节点。遍历单词的每一个字符

检查当前节点是否包含该字符。若不包含直接返回 false,若包含 则 cur 移动到该子节点。字符全部遍历完成后,返回最后节点的 isEnd 标记

true:单词存在

false:只是前缀,不是完整单词

startsWith (prefix) 查找前缀算法步骤:

作用:判断树中是否有以该前缀开头的单词

从根节点开始,cur 指向当前节点。遍历前缀的每一个字符,检查当前节点是否包含该字符。不包含 则 返回 false包含则将 cur 移动到该子节点。所有前缀字符都能顺利走完直接返回 true(不需要判断结尾标记)。

相关推荐
A-刘晨阳1 小时前
当数据学会“秒回“:工业4.0时代的实时计算革命
开发语言·数据库·perl
py有趣1 小时前
力扣热门100题之括号生成
算法·leetcode
沐知全栈开发1 小时前
Lua 基本语法
开发语言
hanbr1 小时前
每日一题day2(Leetcode 704二分查找)
数据结构·算法·leetcode
John.Lewis1 小时前
C++加餐课-stack_queue:反向迭代器
数据结构·c++
云栖梦泽1 小时前
Linux内核与驱动:12.设备树实例分析
linux·c++·单片机
小李子呢02112 小时前
前端八股JS---ES6新增内容
开发语言·javascript·ecmascript
yaoxin5211232 小时前
381. Java IO API - 控制文件树遍历流程
java·开发语言
计算机安禾2 小时前
【数据结构与算法】第45篇:跳跃表(Skip List)
c语言·数据结构·算法·list·排序算法·图论·visual studio