LeetCode 热题 100_实现 Trie (前缀树)(54_208_中等_C++)(图;前缀树;字典树)

@[TOC](LeetCode 热题 100_实现 Trie (前缀树)(54_208))

题目描述:

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

请你实现 Trie 类:

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

输入输出样例:

示例 1:
输入
[“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

题解:

解题思路:

思路一(前缀树(字典树)):

1、解决此问题我们需要了解什么是前缀树,了解其树形结构和特性。
例:
在这里插入图片描述
从上图中我们可以分析出前缀树的一些特性:

① 树形结构:每个节点代表一个字符,根节点代表空字符串。每一条从根节点到叶子节点的路径代表一个字符串。
②共享前缀:所有具有相同前缀的字符串会共享相同的路径(从根节点到某个节点的路径是相同的)。因此,前缀树适合存储一组具有相同前缀的字符串。
③快速查找:通过字符逐一比对的方式,可以在树中快速找到一个完整的字符串或前缀。
④插入和查找效率:前缀树的查找、插入时间复杂度都为 O(L),其中 L 是字符串的长度。由于它基于字符逐层匹配,因此比起常规的哈希表等数据结构在某些场景下效率更高,尤其是当需要进行前缀匹配或字典树操作时。

2、具体思路如下:
通过1中的例题可得
Trie() {} 需要我们根据问题的特性进行树形结构的创建,每个节点代表一个字符,因 a~z 是26个字符,所以我们需要每个节点含有26个指向下一个结点的指针。还需使用一个标志(变量)来存储当前字母是否是单词的最后一个字母。
插入单词到前缀树 insert,进行字母插入时,若之前插入过当前字母则跳过,否则将创建节点。若当前字母是单词的最后一个字母,则进行标记。
查找单词是否在前缀树中存在 search,进行逐个字母的判断,若当前字母不在前缀树中则返回false。若单词中的字母都存在前缀树中,还需判断单词的最后一个字母在前缀树中是否被标记,若已标记则返回true,否则返回false。
检查是否有单词以给定的前缀开始 startsWith ,只需逐个字母进行判断,若当前字母不在前缀树中则返回false。若逐个判断匹配成功则返回true(无需进行单词末尾标记判断)

3、复杂度分析:
① 时间复杂度:初始化为 O(1),其余操作为 O(∣S∣),其中 ∣S∣ 是每次插入或查询的字符串的长度。插入需逐个字母插入,查询需逐个字母进行判断。
② 空间复杂度:O(∣T∣⋅Σ),其中 ∣T∣ 为所有插入字符串的长度之和,Σ 为字符集的大小,本题 Σ=26。

代码实现

代码实现(思路一(前缀树(字典树))):
class Trie {
private://子节点的指针数组,大小为26,代表字母a-zvector<Trie *> children;//标记当前节点是否是一个单词的结尾bool isEnd;// 辅助函数:查找给定前缀路径的最后一个节点Trie* searchPerfix(string prefix){// 从根节点开始Trie* node = this;for (char ch : prefix){// 将字符转换为0到25的索引(a=0, b=1, ..., z=25)ch-='a';  // 如果该子节点不存在,返回空,表示前缀不存在if (node->children[ch] == nullptr)  return nullptr;// 移动到下一个节点node=node->children[ch]; }// 返回最后的节点,表示前缀存在return node;}public:// 构造函数:初始化一个空的Trie树Trie() : children(26),isEnd(false) {}// 插入一个单词到Trie树中void insert(string word) {// 从根节点开始Trie* node=this;for (char ch : word){// 将字符转换为0到25的索引ch -='a';  // 如果该子节点不存在, 创建一个新节点if (node->children[ch]==nullptr){node->children[ch]=new Trie();}//移动到下一个节点node=node->children[ch];}// 设置单词的结尾node->isEnd=true;}// 查找单词是否存在于Trie树中bool search(string word) {//查找单词的路径Trie *node=this->searchPerfix(word); // 如果找到路径且是单词结尾,返回truereturn node !=nullptr && node->isEnd;}// 检查是否存在以给定前缀开头的单词(如果前缀存在,返回true)bool startsWith(string prefix) {return this->searchPerfix(prefix)!=nullptr;}
};
以思路一为例进行调试
#include<iostream>
#include<vector>
using namespace std;class Trie {
private://子节点的指针数组,大小为26,代表字母a-zvector<Trie *> children;//标记当前节点是否是一个单词的结尾bool isEnd;// 辅助函数:查找给定前缀路径的最后一个节点Trie* searchPerfix(string prefix){// 从根节点开始Trie* node = this;for (char ch : prefix){// 将字符转换为0到25的索引(a=0, b=1, ..., z=25)ch-='a';  // 如果该子节点不存在,返回空,表示前缀不存在if (node->children[ch] == nullptr)  return nullptr;// 移动到下一个节点node=node->children[ch]; }// 返回最后的节点,表示前缀存在return node;}public:// 构造函数:初始化一个空的Trie树Trie() : children(26),isEnd(false) {}// 插入一个单词到Trie树中void insert(string word) {// 从根节点开始Trie* node=this;for (char ch : word){// 将字符转换为0到25的索引ch -='a';  // 如果该子节点不存在, 创建一个新节点if (node->children[ch]==nullptr){node->children[ch]=new Trie();}//移动到下一个节点node=node->children[ch];}// 设置单词的结尾node->isEnd=true;}// 查找单词是否存在于Trie树中bool search(string word) {//查找单词的路径Trie *node=this->searchPerfix(word); // 如果找到路径且是单词结尾,返回truereturn node !=nullptr && node->isEnd;}// 检查是否存在以给定前缀开头的单词(如果前缀存在,返回true)bool startsWith(string prefix) {return this->searchPerfix(prefix)!=nullptr;}
};int main(int argc, char const *argv[])
{// 创建一个新的 Trie 对象Trie trie;  // 插入单词 "apple"trie.insert("apple");   // 查找单词apple是否存在,返回 Truecout<<trie.search("apple")<<endl;    // 查找单词apple是否存在,返回 Falsecout<<trie.search("app")<<endl;      // 查找当前存储的单词中是否存在前缀app,返回 Truecout<<trie.startsWith("app")<<endl;  // 插入单词 "app"trie.insert("app");      cout<<trie.search("app")<<endl;      //查找单词app是否存在,返回 Truereturn 0;
}

LeetCode 热题 100_实现 Trie (前缀树)(54_208)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Maui】视图界面与数据模型绑定

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&…

从 Spark 到 StarRocks:实现58同城湖仓一体架构的高效转型

作者&#xff1a;王世发&#xff0c;吴艳兴等&#xff0c;58同城数据架构部 导读&#xff1a; 本文介绍了58同城在其数据探查平台中引入StarRocks的实践&#xff0c;旨在提升实时查询性能。在面对传统Spark和Hive架构的性能瓶颈时&#xff0c;58同城选择StarRocks作为加速引擎&…

探秘 Linux 进程状态:解锁系统运行的密码

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 在 Linux 系统…

深度学习-89-大语言模型LLM之AI应用开发的基本概念

文章目录 1 什么是智能体(Agent)2 什么是大语言模型(LLM)2.1 LLM的训练及使用2.2 Transformer架构2.3 基于LLM的Agent框架3 什么是检索增强生成(RAG)3.1 RAG是什么3.2 生成式AI应用开发3.3 RAG的整体流程3.4 RAG技术3.4.1 简单RAG(Simple RAG)3.4.2 校正RAG(Corrective RAG)3.4…

鸿蒙产业学院正式揭牌!软通动力与深信息签署校企合作框架协议

12月27日&#xff0c;深圳信息职业技术学院&#xff08;简称“深信息”&#xff09;与软通动力信息技术&#xff08;集团&#xff09;股份有限公司&#xff08;简称“软通动力”&#xff09;正式签署校企合作框架协议&#xff0c;并共同揭牌成立鸿蒙产业学院。深信息校长王晖&a…

python轻量级框架-flask

简述 Flask 是 Python 生态圈中一个基于 Python 的Web 框架。其轻量、模块化和易于扩展的特点导致其被广泛使用&#xff0c;适合快速开发 Web 应用以及构建小型到中型项目。它提供了开发 Web 应用最基础的工具和组件。之所以称为微框架&#xff0c;是因为它与一些大型 Web 框架…

2024年河北省职业院校技能大赛 “信息技术应用创新赛项”(高职组)样题解法

​有问题请留言或主页私信咨询 2024年河北省职业院校技能大赛 “信息技术应用创新赛项”&#xff08;高职组&#xff09;样题 一、初始化环境 1.账号及默认密码如表1所示。 表1 账号及密码规划表 账 号密 码root&#xff08;服务端&#xff09;kylin2024!desk&#xff08…

gozero获取数据库内容报错解决方案与实践

这个错误通常出现在 Go 语言的数据库查询中&#xff0c;表示你尝试将一个不支持的数据类型&#xff08;[]uint8&#xff0c;即字节切片&#xff09;存储到一个 Go 类型&#xff08;*time.Time&#xff09;中。具体来说&#xff0c;create_time 列的类型可能是 DATETIME 或 TIME…

【学习笔记15】如何在非root服务器中,安装属于自己的redis

一、下载安装包 官网下载黑马程序员给的安装包&#xff08;redis-6.2.6&#xff09; 二、将安装包上传至服务器 我将安装包上传在我的文件夹/home/XXX&#xff0c;指定路径中/src/local/redis/&#xff0c;绝对路径为/home/XXX/src/local/redis/解压安装包 XXXomega:~$ cd …

PotPlayer 配置安装

文章目录 一、下载1、官网链接2、微软商店 Microsoft Store 二、安装1、双击安装包2、选择字体3、安装向导下一步4、接收许可协议5、选择组件及关联6、选择安装位置7、硬解选项 三、设置1、关闭自动更新2、左键单双击设置3、视频下自动隐藏3.1、效果对比 4、播放信息显示设置4.…

【PCIe 总线及设备入门学习专栏 2 -- PCIe 的 LTSSM 和 Enumeration】

文章目录 OverviewLTSSM StatesDetect StatesDETECT_QUIETDETECT_ACTDETECT_WAITPolling StatesPOLL_ACTIVEPOLL_CONFIGPOLL_COMPLIANCEConfiguration StatesCONFIG_LINKWD_STARTCONFIG_LINKWD_ACCEPTCONFIG_LANENUM_WAITCONFIG_LANENUM_ACCEPTCONFIG_COMPLETECONFIG_IDLERecov…

STM32 FreeROTS Tickless低功耗模式

低功耗模式简介 FreeRTOS 的 Tickless 模式是一种特殊的运行模式&#xff0c;用于最小化系统的时钟中断频率&#xff0c;以降低功耗。在 Tickless 模式下&#xff0c;系统只在有需要时才会启动时钟中断&#xff0c;而在无任务要运行时则完全进入休眠状态&#xff0c;从而降低功…

【机器学习实战中阶】书籍推荐系统

图书推荐系统机器学习项目 通过这个机器学习项目&#xff0c;我们将构建一个图书推荐系统。对于这个项目&#xff0c;我们将使用 K 最近邻&#xff08;K-Nearest Neighbor, KNN&#xff09;算法。 让我们开始构建这个系统。 数据集说明 关于数据集 背景 在过去的几十年中…

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础 目录 1.NAND FLASH 和NOR FLASH异同 ? 2.CPU,MPU,MCU,SOC,SOPC联系与差别? 3.什么是交叉编译&#xff1f; 4.为什么要交叉编译&#xff1f; 5.描述一下嵌入式基于ROM的运行方式和基于RAM的运行方式有什么区别? 1…

【数据分享】1929-2024年全球站点的逐月平均气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正

Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正 1 添加依赖2 测试代码3 测试结果 在OpenCV中&#xff0c;仿射变换&#xff08;Affine Transformation&#xff09;和透视变换&#xff08;Perspective Transformation&#xff09;是两种常用的图像几何变换方法。 变换方…

电梯系统的UML文档07

从这个类中得到的类图&#xff0c;构划出了软件的大部分设计。 系统结构视图提供软件和整个系统结构最复杂的也是最优雅的描述。和通常的软件系统相比&#xff0c;在分布式嵌入系统中了解系统组件如何协同工作是非常重要的。毕竟&#xff0c;每个类图仅仅是一个系统的静态设计…

文本摘要研究:从统计方法到大型语言模型

论文地址&#xff1a;https://arxiv.org/pdf/2406.11289 &#x1f4d6; 文本摘要研究&#xff1a;从统计方法到大型语言模型 近年来&#xff0c;文本摘要研究经历了多次重大变革&#xff0c;从深度神经网络的出现到预训练语言模型&#xff08;PLMs&#xff09;&#xff0c;再到…

MYSQL 5.7数据库,关于1067报错 invalid default value for,解决方法!

???作者&#xff1a; 米罗学长 ???个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 ???各类成品java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot&#xff0c;mysql等项目&#xff0c;源码丰富&#xff0c;欢迎咨询。 ???…

C ++ 也可以搭建Web?高性能的 C++ Web 开发框架 CPPCMS + MySQL 实现快速入门案例

什么是CPPCMS&#xff1f; CppCMS 是一个高性能的 C Web 开发框架&#xff0c;专为构建快速、动态的网页应用而设计&#xff0c;特别适合高并发和低延迟的场景。其设计理念类似于 Python 的 Django 或 Ruby on Rails&#xff0c;但针对 C 提供了更细粒度的控制和更高效的性能。…