【数据结构】前缀树(字典树)汇总
基础
{“a”,“abc”,“bac”,“bbc”,“ca” }的字典树如下图:

最主用的应用:一,字符串编码。二,位运算。
字符串编码
相比利用哈希映射编码,优点如下:
依次查询长度为n的字符串s的前缀时间复杂度是O(n)。查询完s[0…i],再查询s[0…i+1]的时间复杂度是O(1)。而哈希映射的时间复杂度是:O(nn)。
利用哈希映射编码的代码如下:
注意m_iLeafIndex 为-1,表示此节点不是任何字符串的结束字符。
class CStrToIndex
{
public:CStrToIndex() {}CStrToIndex(const vector<string>& wordList) {for (const auto& str : wordList){Add(str);}}int Add(const string& str){if (m_mIndexs.count(str)) { return m_mIndexs[str]; }m_mIndexs[str] = m_strs.size();m_strs.push_back(str);return m_strs.size()-1;}vector<string> m_strs;int GetIndex(const string& str){if (m_mIndexs.count(str)) { return m_mIndexs[str]; }return -1;}
protected:unordered_map<string, int> m_mIndexs;
};
利用字典树编码的代码如下:
template<class TData = char, int iTypeNum = 26, TData cBegin = 'a'>
class CTrieNode
{
public:~CTrieNode(){for (auto& [tmp, ptr] : m_dataToChilds) {delete ptr;}}CTrieNode* AddChar(TData ele, int& iMaxID){
#ifdef _DEBUGif ((ele < cBegin) || (ele >= cBegin + iTypeNum)){return nullptr;}
#endifconst int index = ele - cBegin;auto ptr = m_dataToChilds[ele - cBegin];if (!ptr){m_dataToChilds[index] = new CTrieNode();
#ifdef _DEBUGm_dataToChilds[index]->m_iID = ++iMaxID;m_childForDebug[ele] = m_dataToChilds[index];
#endif}return m_dataToChilds[index];}CTrieNode* GetChild(TData ele){
#ifdef _DEBUGif ((ele < cBegin) || (ele >= cBegin + iTypeNum)){return nullptr;}
#endifreturn m_dataToChilds[ele - cBegin];}
protected:
#ifdef _DEBUGint m_iID = -1;std::unordered_map<TData, CTrieNode*> m_childForDebug;
#endif
public:int m_iLeafIndex = -1;
protected://CTrieNode* m_dataToChilds[iTypeNum] = { nullptr };//空间换时间 大约216字节//unordered_map<int, CTrieNode*> m_dataToChilds;//时间换空间 大约56字节map<int, CTrieNode*> m_dataToChilds;//时间换空间,空间略优于哈希映射,数量小于256时,时间也优。大约48字节
};
template<class TData = char, int iTypeNum = 26, TData cBegin = 'a'>
class CTrie
{
public:int GetLeadCount(){return m_iLeafCount;}CTrieNode<TData, iTypeNum, cBegin>* AddA(CTrieNode<TData, iTypeNum, cBegin>* par,TData curValue){auto curNode =par->AddChar(curValue, m_iMaxID);FreshLeafIndex(curNode);return curNode;}template<class IT>int Add(IT begin, IT end){auto pNode = &m_root;for (; begin != end; ++begin){pNode = pNode->AddChar(*begin, m_iMaxID);}FreshLeafIndex(pNode);return pNode->m_iLeafIndex;} template<class IT>CTrieNode<TData, iTypeNum, cBegin>* Search(IT begin, IT end){auto ptr = &m_root;for (; begin != end; ++begin){ptr = ptr->GetChild(*begin);if (nullptr == ptr){return nullptr;}}return ptr;}CTrieNode<TData, iTypeNum, cBegin> m_root;
protected:void FreshLeafIndex(CTrieNode<TData, iTypeNum, cBegin>* pNode){if (-1 == pNode->m_iLeafIndex){pNode->m_iLeafIndex = m_iLeafCount++;}}int m_iMaxID = 0;int m_iLeafCount = 0;
};
二进制位运算(01前缀树)
比如求nums和x的xor最大值。
将nums放到01放到前缀树中。通过拆位法依次从高到低处理各位,如果x 此为1,则优先选择前缀树的0分支;如果x为0,则优先选择前缀树的1分支。
class C2BNumTrieNode
{
public:C2BNumTrieNode(){m_childs[0] = m_childs[1] = nullptr;}bool GetNot0Child(bool bFirstRight){auto ptr = m_childs[bFirstRight];if (ptr && (ptr->m_iNum > 0)){return bFirstRight;}return !bFirstRight;}int m_iNum = 0;C2BNumTrieNode* m_childs[2];
};template<class T = int, int iLeveCount = 31>
class C2BNumTrie
{
public:C2BNumTrie(){m_pRoot = new C2BNumTrieNode();}void Add(T iNum){m_setHas.emplace(iNum);C2BNumTrieNode* p = m_pRoot;for (int i = iLeveCount - 1; i >= 0; i--){p->m_iNum++;bool bRight = iNum & ((T)1 << i);if (nullptr == p->m_childs[bRight]){p->m_childs[bRight] = new C2BNumTrieNode();}p = p->m_childs[bRight];}p->m_iNum++;}void Del(T iNum){auto it = m_setHas.find(iNum);if (m_setHas.end() == it){return;}m_setHas.erase(it);C2BNumTrieNode* p = m_pRoot;for (int i = iLeveCount - 1; i >= 0; i--){p->m_iNum--;bool bRight = iNum & ((T)1 << i);p = p->m_childs[bRight];}p->m_iNum--;} void Swap(C2BNumTrie<T, iLeveCount>& o) {swap(m_pRoot, o.m_pRoot);swap(m_setHas, o.m_setHas);}C2BNumTrieNode* m_pRoot;std::unordered_multiset<T> m_setHas;
};template<class T = int, int iLeveCount = 31>
class CMaxXor2BTrie : public C2BNumTrie<T, iLeveCount>
{
public:T MaxXor(T iNum){C2BNumTrieNode* p = C2BNumTrie<T, iLeveCount>::m_pRoot;T iRet = 0;for (int i = iLeveCount - 1; i >= 0; i--){bool bRight = !(iNum & ((T)1 << i));bool bSel = p->GetNot0Child(bRight);p = p->m_childs[bSel];if (bSel == bRight){iRet |= ((T)1 << i);}}return iRet;}
};
题解
| 给字符串编码 | 难道分 |
|---|---|
| 字典树】 【哈希表】 【字符串】3076. 数组中的最短非公共子字符串 | 1635 |
| 【字典树(前缀树) 字符串】2416. 字符串的前缀分数和需要记录子孙数量 | 1725 |
| 【字典树 最长公共前缀】1316. 不同的循环子字符串 | 1836 |
| 【字典树(前缀树)】1032. 字符流 | 1970 |
| 【map】【滑动窗口】【字典树】C++算法:2781最长合法子字符串的长度 | 2203 |
| 【字典树】【字符串】【 前缀】3093. 最长公共后缀查询 | 2118 |
| 【字典树】【KMP】【C++算法】3045统计前后缀下标对 II | 2327 |
| 【字典树 离线查询 深度优先】1938. 查询最大基因差 | 2502 |
| 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 | 2695 |
| 【动态规划】 【字典树】C++算法:472 连接词 | |
| 【回溯 字典树(前缀树)】212. 单词搜索 II | |
| 【字典树 马拉车算法】336. 回文对 |
| 01前缀树 | |
|---|---|
| 【字典树】2935找出强数对的最大异或值 II | 2348 |
| 【字典树(前缀树) 异或 离线查询】1707. 与数组中元素的最大异或值 | 2358 |
| 【字典树(前缀树) 位运算】1803. 统计异或值在范围内的数对有多少 | 2479 |
| 其它前缀树 | |
|---|---|
| 【字典树(前缀树) 哈希映射 后序序列化】1948. 删除系统中的重复文件夹需要DFS | 2533 |

扩展阅读
视频课程
有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
相关下载
想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653
| 我想对大家说的话 |
|---|
| 《喜缺全书算法册》以原理、正确性证明、总结为主。 |
| 闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
| 如果程序是一条龙,那算法就是他的是睛 |
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:
【数据结构】前缀树(字典树)汇总
基础 {“a”,“abc”,“bac”,“bbc”,“ca” }的字典树如下图: 最主用的应用:一,字符串编码。二,位运算。 字符串编码 相比利用哈希映射编码,优点如下: 依次查询长度为n的字符串s的前缀时间复杂度是O(…...
Linux:基础开发工具
文章目录 Linux 软件包管理器 yum什么是软件包关于rzsz查看软件包安装软件卸载软件安装扩展源 Linux 编辑器 vimvim的基本概念正常/普通/命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode) vim的基本操作[命令模式]切换至[插入模式][插入模式]切换至[命令模…...
HarmonyOS NEXT Push接入
接入HarmonyOS NEXT Push 推送功能,相比于 Android 真的是简单太多。不再需要适配接入各个厂家的推送 SDK,真是舒服。 1.开通推送服务与配置Client ID 1.1 创建应用获取Client ID 按照官方文档来就可以了:https://developer.huawei.com/co…...
如何快速入门Element-UI:打造高效美观的前端界面
Element-UI 是一款基于 Vue.js 的开源组件库,提供了丰富的 UI 组件,可以帮助开发者快速构建美观、响应式的前端界面。本文将详细介绍如何快速入门 Element-UI,包括环境搭建、组件使用、样式定制及常见问题解决方法,帮助你高效地使用 Element-UI 进行前端开发。 一、环境搭…...
Langchain的向量存储 - Document示例代码里的疑问
文章目录 前言一、语句分析二、 举例解释三、 完整代码总结 前言 之前的代码里有下面这句话,可能有看不明白的读者。 vectors [embeddings.embed(doc.page_content) for doc in docs]今天一起来看下这句话。 一、语句分析 这句话实际上是一个列表推导式&#x…...
Docker 教程-介绍-2
快速了解docker有什么。 Docker简介 Docker 是一个开源的应用容器引擎,基于Go语言开发,并遵循Apache 2.0协议。它允许开发者将应用及其依赖包打包进一个可移植的容器中,这些容器可以发布到任何支持Docker的Linux或Windows机器上,…...
【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 伐木工(200分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 伐木工(200分) 🌍 评测功能需要订阅专栏后私信联系清隆解…...
UltraScale+系列模块化仪器,可以同时用作控制器、算法加速器和高速数字信号处理器
基于 XCZU7EG / XCZU4EG / XCZU2EG • 灵活的模块组合 • 易于嵌入的紧凑型外观结构 • 高性能的 ARM Cortex 处理器 • 成熟的 FPGA 可编程逻辑 ,基于 IP 核的软件库 基于 Xilinx Zynq UltraScaleMPSoC 的 FPGA 技术,采用 Xilinx Zynq UltraScale&a…...
Python与其他编程语言(如Java、C++)相比有哪些优势?
一、技术难点 在探讨Python与其他编程语言相比的优势时,技术难点在于如何全面、准确地把握并阐述这些优势。这需要对Python、Java、C等编程语言有深入的理解,包括它们的语法特性、应用领域、性能特点、开发效率等。 首先,Python的语法简洁明…...
Edge浏览器双击关闭标签页,双击关闭浏览器选项卡
设置》外观》自定义浏览器,开启“使用双击关闭浏览器选项卡” 设置里面搜索“双击”,这是最快的方式 鼠标滚轮单击 或者进入“设置”-“辅助功能” 呼吁已久的功能来了!Edge浏览器双击关闭标签页功能上线新 国产浏览器大多都有双击关闭标签页…...
C++ 贪心算法——跳跃游戏、划分字母区间
一:跳跃游戏 55. 跳跃游戏 题目描述:给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ࿱…...
汽车数据应用构想(三)
上期说的,用数据去拟合停车信息的应用,那么类似的POI信息相关的场景其实都可以实现。今天讲讲用户使用频率也很高的加油/充电场景。 实际应用中,在加油场景中用户关心的通常还是价格。无论是导航还是各种加油APP/小程序,都已经很…...
体素技术在AI绘画中的革新作用
随着人工智能技术的不断进步,AI绘画已经成为艺术创作和视觉设计领域的一大趋势。在众多推动AI绘画发展的技术中,体素技术以其独特的优势,正在逐渐改变着我们对计算机生成图像的认识。本文旨在探讨体素技术在AI绘画中的应用与影响,…...
Leetcode.866 回文质数
题目链接 Leetcode.866 回文质数 rating : 1938 题目描述 给你一个整数 n n n ,返回大于或等于 n n n 的最小 回文质数。 一个整数如果恰好有两个除数: 1 1 1 和它本身,那么它是 质数 。注意, 1 1 1 不是质数。 例如…...
【论文阅读】Point2RBox (CVPR’2024)
paper:https://arxiv.org/abs/2311.14758 code:https://github.com/yuyi1005/point2rbox-mmrotate...
深度学习的点云分割
深度学习的点云分割 点云分割是计算机视觉中的一个重要任务,特别是在三维数据处理和分析中。点云数据是由大量三维点构成的集合,每个点包含空间坐标(x, y, z),有时还包含其他信息如颜色和法向量。点云分割的目标是将点…...
【知识点】c++模板特化
在 C 中,模板特化分为全特化(full specialization)和偏特化(partial specialization)。它们允许程序员为特定类型或类型模式提供不同的实现,以覆盖通用模板的默认行为。 模板全特化 模板全特化是指为某个…...
算法家族之一——二分法
目录 算法算法的打印效果如果算法里的整型“i”为1如果算法里的整型“i”为11 算法的流程图算法的实际应用总结 大家好,我叫 这是我58,现在,请看下面的算法。 算法 #define _CRT_SECURE_NO_WARNINGS 1//<--预处理指令 #include <stdi…...
【深度学习】PuLID: Pure and Lightning ID Customization via Contrastive Alignment
论文:https://arxiv.org/abs/2404.16022 代码:https://github.com/ToTheBeginning/PuLID 文章目录 AbstractIntroductionRelated WorkMethods Abstract 我们提出了一种新颖的、无需调整的文本生成图像ID定制方法——Pure and Lightning ID customizatio…...
Elastic 8.14:用于简化分析的 Elasticsearch 查询语言 (ES|QL) 正式发布
作者:来自 Elastic Brian Bergholm 今天,我们很高兴地宣布 Elastic 8.14 正式发布。 什么是新的? 8.14 版本最重要的标题是 ES|QL 的正式发布(GA),它是从头开始设计和专门构建的,可大大简化数据调查。在新的查询引擎的…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
