一、什么是Trie?

Trie(发音为"try"),也称为字典树、前缀树,是一种多叉树结构,专门用于高效存储和检索字符串集合。其核心特点是共享字符串的公共前缀,从而大幅减少冗余存储,同时加快查询速度。

例如,存储字符串 “apple”、“app”、“apricot” 时,Trie会共享前缀 “ap”,结构如下(简化示意):

根节点
|
a
|
p
/ \
p   r
|   |
l   i
|   |
e  ...

二、Trie的结构

Trie的基本组成单位是节点(Node),每个节点包含:

  1. 子节点指针数组:用于指向后续字符(如存储26个小写字母时,数组大小为26)。
  2. 结束标志(isEnd):布尔值,标记当前节点是否为某个字符串的结尾。

根节点是特殊节点,不存储任何字符,仅作为所有字符串的起始点。

从根节点到任意一个标记为isEnd = true的节点的路径,构成一个完整的字符串。

三、Trie的基本操作

Trie的核心操作包括插入(insert)查找(search)前缀查询(startsWith),三者的时间复杂度均为O(L)O(L)O(L),其中LLL是字符串的长度。

1. 插入(Insert)

目标:将字符串s插入Trie中。

步骤

  1. 从根节点开始遍历。
  2. 对字符串s的每个字符c
  • 计算字符在数组中的索引(如 c - 'a',假设为小写字母)。
  • 若当前节点的子节点中不存在c,则创建新节点。
  • 移动到对应子节点。
  1. 遍历结束后,将最后一个节点的isEnd标记为true(表示该节点是字符串的结尾)。

2. 查找(Search)

目标:判断字符串s是否在Trie中。

步骤

  1. 从根节点开始遍历。
  2. 对字符串s的每个字符c
  • 若当前节点的子节点中不存在c,直接返回false
  • 移动到对应子节点。
  1. 遍历结束后,返回最后一个节点的isEnd值(只有isEnd = true才表示完整字符串存在)。

3. 前缀查询(StartsWith)

目标:判断Trie中是否存在以字符串s为前缀的字符串。

步骤

  1. 与查找操作类似,从根节点开始遍历每个字符。
  2. 若任何字符不存在,返回false
  3. 遍历结束后,直接返回true(无需检查isEnd,因为前缀本身不需要是完整字符串)。

四、时间复杂度分析

  • 插入:遍历字符串的每个字符,时间复杂度为O(L)O(L)O(L)LLL为字符串长度)。
  • 查找:同样遍历每个字符,时间复杂度为O(L)O(L)O(L)
  • 前缀查询:与查找相同,时间复杂度为O(L)O(L)O(L)

相比哈希表(平均O(1)O(1)O(1),但最坏O(N⋅L)O(N \cdot L)O(NL)NNN为字符串数量),Trie在前缀匹配场景(如自动补全)中更高效,且时间复杂度更稳定。

五、C++代码实现

1. 节点结构定义

struct TrieNode {// 子节点数组:假设只存储小写字母,共26个TrieNode* children[26];// 标记当前节点是否为字符串的结尾bool isEnd;// 构造函数:初始化子节点为nullptr,isEnd为falseTrieNode() {for (int i = 0; i < 26; ++i) {children[i] = nullptr;}isEnd = false;}
};

2. Trie类实现

3. 使用示例

#include <iostream>
int main() {Trie trie;// 插入字符串trie.insert("apple");trie.insert("app");// 查找测试cout << trie.search("apple") << endl;   // 输出1(true)cout << trie.search("app") << endl;     // 输出1(true)cout << trie.search("ap") << endl;      // 输出0(false,不是完整字符串)// 前缀查询测试cout << trie.startsWith("ap") << endl;  // 输出1(true,有"apple"和"app")cout << trie.startsWith("banana") << endl;  // 输出0(false)return 0;
}

六、Trie的应用场景

  1. 自动补全:如搜索引擎输入前缀后提示完整内容。
  2. 拼写检查:判断单词是否存在于词典中。
  3. IP路由:最长前缀匹配算法(Longest Prefix Matching)。
  4. 单词游戏:如Scrabble中判断单词是否有效。

七、总结

Trie是一种针对字符串集合的高效数据结构,通过共享前缀实现快速插入、查找和前缀匹配。其核心优势是:

  • 时间复杂度稳定(O(L)O(L)O(L)),不受字符串数量影响。
  • 前缀匹配能力强,适合特定场景。

缺点是空间消耗可能较大(每个节点需要存储26个指针),但在实际应用中(如词典、路由表),其效率优势往往超过空间成本。

掌握Trie对于解决字符串相关的算法题(如LeetCode 208. 实现Trie)非常重要,建议结合实际题目练习加深理解。

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

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

相关文章

Laya使用VideoNode动态加载视频,可以自定义播放视频此处以及位置

export class VideoCommand {video: Laya.VideoNode;public duration: number 0;/*** param videoPos 视频位置* param videoSize 视频大小*/public constructor(videoPos: Laya.Vector2, videoSize: Laya.Vector2) {this.video new Laya.VideoNode;//添加到舞台 1是场景中的…

yum localinstall安装本地包

yum localinstall 是一个用于安装本地 RPM 包并自动处理依赖关系的命令。当你有一个或多个本地的 RPM 包需要安装,又希望 yum 能帮你解决可能存在的依赖问题时,这个命令就非常有用。下面我会详细解释它的用法和注意事项。 🖥️ 命令基本用法 yum localinstall 命令的基本…

LeetCode 面试经典 150 题:轮转数组(三次翻转法详解 + 多解法对比)

在数组类算法题中&#xff0c;“轮转数组” 是一道考察 “原地操作” 与 “逻辑转换” 能力的经典题目。所谓 “轮转”&#xff0c;是指将数组元素向右移动指定步数&#xff0c;且超出数组长度的元素需 “循环” 到数组开头。这道题的最优解 ——三次翻转法&#xff0c;能以 O …

网络编程---TCP

1.TCP&#xff1a;传输控制协议&#xff0c;位于传输层2.TCP的特性&#xff1a;a.使用流式套接字&#xff0c;数据连续&#xff0c;有顺序b.TCP是可靠传输&#xff0c;有有应答机制ACK&#xff0c;即收到数据后会明确告知发送方已收到数据&#xff1b;若发送方没有在预计时间收…

对计算机网络模型的理解

文章目录 目录 前言 一、Internet 的核心特点 二、Internet 的组成结构 1. 硬件基础&#xff1a;网络运行的 “物理载体” 2. 软件支撑&#xff1a;网络运行的 “功能桥梁” 3. 协议规则&#xff1a;网络运行的 “通用语言” 三、OSI 七层参考模型&#xff08;理论标准&…

每日一算:分发糖果

在算法面试中&#xff0c;“分发糖果” 是一道经典的贪心算法应用题&#xff0c;核心考察对 “局部最优推导全局最优” 的理解。本文将从问题分析出发&#xff0c;提供两种主流解题思路&#xff0c;并附上 C 实现代码&#xff0c;帮助你彻底掌握这道题。一、问题重述题目要求有…

【WorkManager】无法在 Direct Boot 模式下初始化

【WorkManager】无法在 Direct Boot 模式下初始化一、问题描述二、问题分析2.1 关于 Direct Boot 模式2.2 支持 Direct Boot 模式2.3 手动初始化 WorkManager 组件2.4 WorkManager 不支持 Direct Boot 的官方修改三、解决方案一、问题描述 在使用 WorkManager 库来实现开机上报…

Hybrid应用性能优化实战分享(本文iOS 与 H5为例,安卓同理)

前言在移动应用开发中&#xff0c;Hybrid 架构因其跨平台特性和开发效率优势被广泛采用。然而&#xff0c;WebView 的性能问题一直是开发者面临的挑战。本文将基于实际项目经验&#xff0c;分享 iOS Hybrid 应用的核心优化策略&#xff0c;涵盖 WebView 池化、预加载、用户体验…

点积、叉积、矩阵行列式详解、线性相关与线性无关、矩阵的秩、矩阵可逆与不可逆详解

1.向量 1.1 点积&#xff08;Dot Product&#xff09; 1.1.1 定义 点积是在求一个标量&#xff0c;点积结果没有方向。 对于两个向量u(u1,u2,u3),v(v1,v2,v3)\bold{u}(u_1,u_2,u_3),\bold{v}(v_1,v_2,v_3)u(u1​,u2​,u3​),v(v1​,v2​,v3​) 点积定义为&#xff1a;u⋅vu1v1u…

Mac安装nvm详细教程(超简单)

本章教程,主要介绍如何在Mac操作系统上安装nvm. 我们使用官方一键安装脚本,完成安装 一、安装步骤 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash配置环境变量,编辑.zshrc文件 vim .zshrcexport NVM_DIR="$(

【selenium】网页元素找不到?从$(‘[placeholder=“手机号“]‘)说起

网页元素找不到&#xff1f;从$(‘[placeholder“手机号”]’)说起总结&#xff1a;控制台不骗人&#xff0c;元素选不到&#xff0c;八成是写法、时机或环境的问题。我们在写网页自动化脚本或者调试页面的时候&#xff0c;经常遇到一个让人头疼的问题&#xff1a;明明元素就在…

SSE 模仿 GPT 响应

后端代码 const express require(express) const cors require(cors);const app express(); app.use(cors()); const port 3000;app.listen(port, () > {console.log(Server running at http://localhost:${port}/); });const msg 全国同胞们&#xff0c; 尊敬的各位国…

MAC 多个版本 JDK进行切换

1.查看本机所有的jdk/usr/libexec/java_home -V2、打开bash_profile文件。可以在终端vim ~/.bash_profile打开&#xff0c;也可以打开访达shiftcmdG然后输入/Users/mac/.bash_profile&#xff08;本机bash_profile的路径&#xff09;加入新的环境变量格式如下&#xff08;参考我…

shell 中 expect 详解

一、概述Expect是一个免费的编程工具语言&#xff0c;用来实现自动和交互式任务进行通信&#xff0c;而无需人的干预。Expect的作者DonLibes在1990年开始编写Expect时对Expect做有如下定义&#xff1a;Expect是一个用来实现自动交互功能的软件套件。通过expect系统管理员可以创…

第4讲 机器学习基础概念

机器学习作为人工智能的子领域&#xff0c;专注于训练计算机算法自动发现数据中的模式与关联关系。以下是其核心基础概念&#xff1a;4.1 数据数据是机器学习的基石。缺乏数据&#xff0c;算法将无从学习。数据可呈现为结构化数据&#xff08;如电子表格、数据库&#xff09;和…

Go组合式继承:灵活替代方案

Go 语言没有传统面向对象编程中的继承机制&#xff0c;但通过组合和接口实现类似功能。Go 更提倡组合优于继承的设计原则&#xff0c;这种设计方式更灵活且易于维护。结构体组合&#xff08;伪继承&#xff09;通过嵌套结构体实现类似继承的效果。子结构体可以直接访问父结构体…

Verilog三段式FSM,实现十字路口红绿灯

运行环境&#xff1a;VCS verdi状态说明&#xff1a;S0 &#xff1a; 初始状态 S1 &#xff1a; 东西方向绿灯亮&#xff0c;南北方向红灯亮&#xff1b;点亮30周期 S2 &#xff1a; 东西方向黄灯亮&#xff0c;南北方向红灯亮&#xff1b;点亮2 周期 S3 &#xff1a; 东西方向…

java 将pdf转图片

如何将pdf文件转为图片 import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class Pdf2Png {/**…

手搓Spring

目录 两种方法创建Spring容器 自定义Spring容器及前置操作 Spring扫描逻辑实现 createBean()方法 getBean()方法 依赖注入&#xff08;DI&#xff09; BeanNameAware接口 InitializingBean接口 BeanPostProcessor接口 AOP的实现 Spring 是一个轻量级的 Java 开发框架…

.NET 单文件程序详解:从原理到实践

C# 混淆加密大师在最新版本中, 提供了.NET单文件解包打包功能, 它可以快速解包官方打包的单文件程序&#xff0c;恢复为原始的多文件结构。也可以对解包后的程序集进行混淆与加密&#xff0c;有效提升逆向门槛。最后还能重新打包成单文件程序&#xff0c;保持对用户友好的分发形…