Trie树专题

2024-09-02 06:44
文章标签 专题 trie

本文主要是介绍Trie树专题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Intro:

        为了高效的存储和查找字符串,集合的数据结构。,

 板子:

/*Trie树 —— 模板题 AcWing 835. Trie字符串统计*/
int son[N][26], cnt[N], idx;
// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// cnt[]存储以每个节点结尾的单词数量// 插入一个字符串
void insert(char *str)
{int p = 0;for (int i = 0; str[i]; i ++ ){int u = str[i] - 'a';if (!son[p][u]) son[p][u] = ++ idx;p = son[p][u];}cnt[p] ++ ;
}// 查询字符串出现的次数
int query(char *str)
{int p = 0;for (int i = 0; str[i]; i ++ ){int u = str[i] - 'a';if (!son[p][u]) return 0;p = son[p][u];}return cnt[p];
}
// 正常遍历完后的p就是指向最后一个字符。

AcWing 835. Trie字符串统计 

#include<iostream>
using namespace std;
int t;
const int N = 1e5 + 10;
int son[N][27], cnt[N], idx;
string x;void insert(string str){int p = 0;for(int i = 0; i < str.length(); i ++){int u =  str[i] - 'a';if(!son[p][u])  son[p][u] = ++ idx;p = son[p][u];}cnt[p] ++;
}int query(string str){int p = 0;for(int i = 0; str[i]; i ++){int u = str[i] - 'a';if(!son[p][u])  return 0;p = son[p][u];}return cnt[p];
}int main(){cin >> t;while (t --){string op;  cin >> op >> x;if(op[0] == 'I')    insert(x);else    cout << query(x) << endl;}return 0;
}

======异或字典树/01字典树======

AcWing 143. 最大异或对

        着重关注一下如何估计结点数目的上限M. 

#include<iostream>
using namespace std;
const int N = 1e5 + 10, M = 30 * N + 10;    
// M是估计节点数目的上限 = 单词个数(N) * 平均单词长度(30)
int a[N], son[M][2], idx;void insert(int x){int p = 0;for(int i = 0; i < 31; i ++){// 错误写法:int u = x & (1 << (30 - i));   与的结果并非-或1int u = (x >> (30 - i)) & 1;if(!son[p][u])  son[p][u] = ++ idx;p = son[p][u];  // 移动}
}// func: 能够与num异或运算得到最大数值的数(在数组中)
int query(int num){int p = 0;int res = 0;for(int i = 0; i < 31; i ++){int u = (num >> (30 - i)) & 1;if(!son[p][!u]) res = (res << 1) + u, p = son[p][u];        // 相反方向不存在else    res = (res << 1) + !u, p = son[p][!u];              // 相反方向存在}return res;
}int main(){int n;  cin >> n;for(int i = 0; i < n; i ++) {cin >> a[i];insert(a[i]);}int res = 0;for(int i = 0; i < n; i ++)res = max(res, a[i] ^ query(a[i]));cout << res;return 0;
}

AcWing 3485. 最大异或和

Leetcode 208. 实现 Trie (前缀树)

注意下search和startswith的判别即可。 

class Trie {
public:const static int N = 3e4 * 20;int son[N][26], cnt[N], idx;
public:Trie() {idx = 0;memset(son, 0, sizeof(son));memset(cnt, 0, sizeof(cnt));}void insert(string word) {int p = 0;for(int i = 0; i < word.length(); i ++){int u = word[i] - 'a';if(!son[p][u])  son[p][u] = ++ idx;p = son[p][u];}cnt[p] ++;}bool search(string word) {int p = 0;for(int i = 0; i < word.length(); i ++){int u = word[i] - 'a';if(!son[p][u])  return false;p = son[p][u];}return cnt[p];}bool startsWith(string prefix) {int p = 0;for(int i = 0; i < prefix.length(); i ++){int u = prefix[i] - 'a';if(!son[p][u])  return false;p = son[p][u];}return true;}
};

Leetcode 676. 实现一个魔法字典 

方法一:(暴力)哈希字符串长度

class MagicDictionary {
public:
unordered_map<int, vector<string>> hash;MagicDictionary() {}void buildDict(vector<string> dictionary) {for(auto& v: dictionary){int len = v.length();hash[len].push_back(v);}}bool search(string searchWord) {int slen = searchWord.length();if(hash.count(slen) == 0)   return false;// 如果长度相等的话,才有可能替换一个字母匹配上int cnt = 0;        // 变成2直接false,for结束若仍然为0也是falsebool fd = false;for(auto& dicstring: hash[slen]){cnt = 0;for(int i = 0; i < slen; i ++){if(dicstring[i] != searchWord[i]){cnt ++;if(cnt == 2)    break;}}   if(cnt == 1){fd = true;  break;}}return fd;}
};

方法二:(Trie)优化枚举+dfs

class MagicDictionary {
public:const static int N = 1e5 + 10;int son[N][26], cnt[N], idx;
public:MagicDictionary() {idx ++;memset(son, 0, sizeof(son));memset(cnt, 0, sizeof(cnt));}void buildDict(vector<string> dictionary) {auto insert = [&](string x) -> void{int p = 0;for(int i = 0; i < x.length(); i ++){int u = x[i] - 'a';if(!son[p][u])  son[p][u] = ++ idx;p = son[p][u];}cnt[p] ++;};for(auto& v: dictionary)    insert(v);}bool search(string searchWord) {function<bool(int, int, int)> dfs=[&](int p, int idx, bool modi)->bool{if(idx == searchWord.size())return modi && cnt[p];   // 修改过一次&&终止int u = searchWord[idx] - 'a';if(son[p][u])  // 存在的话, 可以继续往下走if(dfs(son[p][u], idx + 1, modi))return true;// 如果还没修改过, 可以修改为任意除了原本元素的其他字母if (!modi){for(int i = 0; i < 26; i ++){if (i != u && son[p][i])if(dfs(son[p][i], idx + 1, true))return true;}}return false;};return dfs(0, 0, false);}
};

这篇关于Trie树专题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1129289

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

数字电路专题:verilog 阻塞赋值和非阻塞赋值

verilog 阻塞赋值 和 非阻塞赋值 “=”阻塞赋值, ”<=”非阻塞赋值。阻塞赋值为执行完一条赋值语句,再执行下一条,可理解为顺序执行,而且赋值是立即执行; 非阻塞赋值可理解为并行执行,不考虑顺序,在 always 块语句执行完成后,才进行赋值。 如下面的阻塞赋值: //代码如下:module top(din,a,b,c,clk);input din;input clk;out

算法专题一: 双指针

目录 前言1. 移动零(easy)2. 复写零(easy)3. 快乐数(medium)4. 盛水最多的容器(medium)5. 有效三角形的个数(medium)6. 和为 s 的两个数字(easy)7. 三数之和(medium)8. 四数之和(medium) 前言 常见的双指针有两种形式,一种是对撞指针,一种是左右指针。 1. 对撞指针: ⼀般用于顺序结构中,也称左右指针。

《黑神话:悟空》专题合集MOD/修改器/壁纸/音乐/CG剧情

《黑神话:悟空》专题合集」 链接:https://pan.quark.cn/s/d67857f4e308 包含内容: 《黑神话:悟空》MOD合集 《黑神话:悟空》修改器(风灵月影) 《黑神话:悟空》壁纸合集 《黑神话:悟空》3小时CG完整剧情合集 4K120帧最高画质!国语 简中字幕 附:4K 结尾动画合集 ​​​国语 简中字幕 《黑神话:悟空》主题曲 《黑神话

2014暑假集训搜索专题

A - 漫步校园 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划

2014级寒假特训之并查集专题

Problem A: Double和XXZ的生日宴请 Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 9   Solved: 7 [ Submit][ Status][ Web Board] [ Edit] [ TestData] Description Double 和 XXZ同一天生日,他们俩30岁生日那天,当年

算法_栈专题---持续更新

文章目录 前言删除字符中的所有相邻重复项题目要求题目解析代码如下 比较含退格的字符串题目要求题目解析代码如下 基本计算器II题目要求题目解析 字符串解码题目要求题目解析代码如下 验证栈序列题目要求题目解析代码如下 前言 本文将会向你介绍有关栈的相关题目:删除字符中的所有相邻重复项、比较含退格的字符串、基本计算器II、字符串解码、验证栈序列 删除字符中的所有相邻重复项 htt