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(不需要判断结尾标记)。

相关推荐
知识汲取者13 分钟前
巨量引擎 Marketing API Java SDK 介绍
java·开发语言
182******208315 分钟前
2026年40岁自学java还能找到工作吗
java·开发语言
yuzhiboyouye32 分钟前
java线程池
java·开发语言·firefox
zh_xuan1 小时前
使用命令行把安装包上传到github
c++·git·libcurl·c++工程打包
无限进步_3 小时前
二叉搜索树完全解析:从概念到实现与应用场景
c语言·开发语言·数据结构·c++·算法·github·visual studio
努力努力再努力FFF3 小时前
别再乱学PS、Python了,普通大学生该看懂的技能趋势
开发语言·python
鱼跃厂长3 小时前
这份skill,能将你的简历提升到字节的水平!
c++·ai·ai编程
天若有情6733 小时前
逆向玩家狂喜!用C++野生写法一键破解线性加密(不规范但巨好用)
开发语言·c++·算法
XiYang-DING3 小时前
JavaScript
开发语言·javascript·ecmascript