字典树/前缀树

Trie(发音类似 “try”)或者说 前缀树(字典树) 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。主要思想是利用字符串的公共前缀来节约存储空间。很好地利用了串的公共前缀,节约了存储空间。字典树主要包含两种操作,插入和查找。

比如,我们要怎么用树存下单词"abc",“abb”,“bca”,"bc"呢?见图
在图中,红点代表有一个以此节点为终点的单词。然后,我们如果要查找某个单词如s=“abc”,就可以这样

在这里,s=“abc” 的每一个字母都在树中被查到了,并且最后一个点是红色代表有一个在此结束的单词,查询成功。而 s=“bb” 的第二个字母没有在相应位置被查到,因此"bb"不在字典中。至于s=“ab” 虽然单词中每个点都被查到了,但是由于结尾的字母在树中没有标红,因此也是不在字典中。

对于字典树的每次查找,时间复杂度为log级别,比暴力快多了。

例题

字典树有多中实现方法,可以通过数组存储,也可以通过哈希表来存储,本文我们主要讲解这两中方法:

力扣208题:实现 Trie (前缀树)

请你实现 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 次

实现(Java)

class Trie {private Trie[] children;     // 存放子结点,当不为null时,即当前位置被激活private boolean isEnd;          // 判断此位置是否是单词的结尾public Trie() {children = new Trie[26];}public void insert(String word) {Trie node = this;     for(int i = 0; i < word.length(); i++) {char ch = word.charAt(i);int index = ch - 'a';if(node.children[index] == null) {node.children[index] = new Trie();}node = node.children[index];}node.isEnd = true;}public boolean search(String word) {Trie node = this;for(int i = 0; i < word.length(); i++) {char ch = word.charAt(i);int index = ch - 'a';if(node.children[index] == null) {return false;}node = node.children[index];}return node != null && node.isEnd == true;}public boolean startsWith(String prefix) {Trie node = this;for(int i = 0; i < prefix.length(); i++) {char ch = prefix.charAt(i);int index = ch - 'a';if(node.children[index] == null) {return false;}node = node.children[index];}return true;}
}/*** Your Trie object will be instantiated and called as such:* Trie obj = new Trie();* obj.insert(word);* boolean param_2 = obj.search(word);* boolean param_3 = obj.startsWith(prefix);*/

力扣648题:单词替换

在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

现在,给定一个由许多词根组成的词典 dictionary 和一个用空格分隔单词形成的句子 sentence。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

你需要输出替换之后的句子。

示例 1:

输入:dictionary = [“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”

示例 2:

输入:dictionary = [“a”,“b”,“c”], sentence = “aadsfasf absbs bbab cadsfafs”
输出:“a a b c”

提示:

  • 1 <= dictionary.length <= 1000
  • 1 <= dictionary[i].length <= 100
  • dictionary[i] 仅由小写字母组成。
  • 1 <= sentence.length <= 10^6
  • sentence 仅由小写字母和空格组成。
  • sentence 中单词的总量在范围 [1, 1000] 内。
  • sentence 中每个单词的长度在范围 [1, 1000] 内。
  • sentence 中单词之间由一个空格隔开。
  • sentence 没有前导或尾随空格。

实现(Java)

class Solution {public String replaceWords(List<String> dictionary, String sentence) {Trie trie = new Trie();for(String word : dictionary) {Trie cur = trie;for(int i = 0; i < word.length(); i++) {char ch = word.charAt(i);cur.children.putIfAbsent(ch, new Trie());cur = cur.children.get(ch);}cur.children.put('#', new Trie());}String[] words = sentence.split(" ");for(int i = 0; i < words.length; i++) {words[i] = find(words[i], trie);}return String.join(" ", words);}public String find(String word, Trie trie) {for(int i = 0; i < word.length(); i++) {if(trie.children.containsKey('#'))return word.substring(0, i);Character ch = word.charAt(i);if(!trie.children.containsKey(ch)) {return word;}trie = trie.children.get(ch);}return word;}}class Trie {  // 哈希表存放<字符, 下一个字符>,注意当下一个字符有'#'时表示该字符为单词结尾Map<Character, Trie> children; public Trie() {children = new HashMap<Character, Trie>();}
}

前缀树就先总结到这里,之后遇到其他方法还会继续更新哦,谢谢大家的点赞支持!

Trie(字典树/前缀树)相关推荐

  1. 字典数(前缀树)的实现

    [题目] 字典树又称为前缀树或者Trie树,是处理字符串常用的数据结构.假设组成所有单词的字符仅是'a'-'z',请实现字典树的结构,并包含以下四个主要的功能. void insert(String ...

  2. Trie(前缀树/字典树)及其应用

    from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...

  3. 提高篇 第二部分 字符串算法 第3章 Trie字典树

    Trie(字典树)解析及其在编程竞赛中的典型应用举例 - Reqaw - 博客园 『一本通』Trie字典树 - YeLingqi - 博客园 字典树(Trie Tree) - 仰望高端玩家的小清新 - ...

  4. 字典树实现_【Leetcode每日打卡】单词的压缩编码 Trie(字典树)入门

    一.前言(鸡汤(一段废..话..可以跳过啦)) 同学们好!没想到我这个小小的公众号破千粉啦,对于大佬们而言或许不值一提,但是对我而言是一个莫大的鼓舞!更加坚定了我持续输出优质内容的决心.希望我们都能每 ...

  5. trie树查找前缀串_Trie数据结构(前缀树)

    trie树查找前缀串 by Julia Geist Julia·盖斯特(Julia Geist) A Trie, (also known as a prefix tree) is a special ...

  6. python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)...

    python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie) 主要包括两部分内容: (1)利用python中的dict实现Trie: ( ...

  7. C++简单实现 前缀树

    今天在leetcode上面看了一道题(第208题),问题是如何实现一个字符串前缀树,能够实现字符串的插入,查找和查找前缀功能.在这里记录一下前缀树的实现: class Trie { public:/* ...

  8. 前缀树介绍,定义,图文详解分析——Java/Kotlin双版本代码

    前缀树 前缀树,又称作字典树,用一个树状的数据结构储存字典中的所有单词. 列,一个包含can.cat.come.do.i.in.inn的前缀树如下图所示: 前缀树是一个多叉树,一个节点可能存在多个节点 ...

  9. 【前缀树】写一个敏感词过滤器

    1.什么是敏感词过滤 这其实是一个很常见的功能,随处可见以至于你可能都没关注过,基本上在有评论的地方都会有它的身影. 举例来说,你打游戏和别人对喷的时候,是不是一些脏话发不出去哈哈,这些词汇会用*** ...

最新文章

  1. Intellij Idea 生成serialVersionUID的方法
  2. 一文概览深度学习中的激活函数
  3. 生信和植物领域最新资讯合集
  4. 服务器的图片无法显示,服务器的图片无法显示
  5. [材料力学]弯扭组合梁实验报告
  6. maven入门(7)maven项目(组件)的坐标
  7. springboot-web进阶(三)——统一异常处理
  8. 手机和PC机根本不能挖矿
  9. RHEL7及CentOS7的语言、字符编码、键盘映射、X11布局设置(localectl)-系统管理(1)...
  10. git 从远程git服务上拉代码 git服务器非默认端口
  11. ARINC 429总线学习资料?
  12. 百度SEO与SEM的区别
  13. Django教程(自强学堂)
  14. java 北京时区_世界时区和Java时区详解
  15. ARM发布Cortex-X1,是为了向苹果自研A系列处理器发起冲击吗?
  16. PatternLayout格式解读
  17. FastDFS - 分布式文件存储系统
  18. MySql数据类型-读书笔记
  19. 基于SSM框架大型分布式电商系统开发(1-2)
  20. 实测几款常见的DNS,看防护能力怎么样?

热门文章

  1. PhysX3.4文档(12) -- Geometry Queries
  2. Groundhog Chasing (数论质因数)
  3. 细说Redirect重定向请求
  4. 2023热销护眼灯品牌:大国品牌,爱德华医生护眼灯52年匠心之路
  5. backlog配置_redis的tcp-backlog配置
  6. TCP backlog
  7. 跨平台技术实践案例: 用 reactxp 重写墨刀的移动端
  8. 蚂蚁数据分析平台的演进及数据分析方法的应用
  9. rapidjson指针
  10. 如何真正的赚钱,赚大钱?