当前位置: 首页 > news >正文

从零学算法208

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

  • 定义树中每个节点包含子节点数组,记录下一个字符的所有可能性,对该题而言只可能为 26 个字符中的一个,所以初始化时长度为 26 即可,再添加一个变量 isEnd 记录当前节点对应的字符是否为某个单词的尾字符,就能满足 search 函数的需求。(这里当前节点对应的字符,其实被隐含在它属于父节点的子节点数组中第几位,具体看代码)
  • 插入字符串时,遍历它,只要当前字符不在树的这一层的可能性中,就加入该可能,否则就直接去往下一层,等待判断下一个字符是否在下一层。
  • 比如字符串 abc 被插入,我们用数组层数表示树的层数,会得到 [a,[b,[c]]],并且 c 为某个字符串结尾,再插入 ade 会得到 [a,[b,d,[c,e]]],并且 e 也为某个字符串结尾
  • 这样比如判断是否包含前缀 ab,我们就先看第一层是否包含 a,然后去下一层看是否包含 b
  • 而判断是否包含某个完整的字符,在 insert 完一个单词后,我们会在树中对应那层的那个节点记录状态为 isEnd,表示是某个单词的结尾,调用 search 时遍历到这一层的这个节点时判断 isEnd 即可
  •   class Trie {// 记录下一位可能的字符Trie[] children;boolean isEnd;public Trie() {this.children = new Trie[26];this.isEnd = false;}public void insert(String word) {// 获取根节点Trie node = this;for(char ch:word.toCharArray()){// 获取当前字符对应下标int index = ch-'a';// 如果未记录就记录当前字符并为该节点新建一个字典树if(node.children[index] == null)node.children[index] = new Trie();// 移动到下一个节点去记录包含字母的可能性// 移动后的此时的 node 对应字符 ch,因为它是父节点的第 index 个子节点// index 为 0 对应字符 'a',1对应 'b'... 25 对应 'z'node = node.children[index];}node.isEnd = true;}public boolean startsWith(String prefix) {Trie node = this;// 按顺序寻找树中是否存在一条遍历路径,从头开始包含 prefix 的每个字符for(char c:prefix.toCharArray()){int index = c-'a';// 只要有一个字符不被包含在可能的下一个字符,就表示不存在该前缀if(node.children[index] == null)return false;// 存在就继续验证下个字符是否依旧存在node = node.children[index];}return true;}// 相较于 startsWith 就是多了一个 isEnd 的验证public boolean search(String word) {Trie node = this;for(char c:word.toCharArray()){int index = c-'a';if(node.children[index] == null)return false;node = node.children[index];}// 如果最后的字符是尾字符才表示树中包含 word// 但是这不代表这个字符就不能有后面的字符了,只是对于某个单词而言是尾字符return node.isEnd;}}/*** 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);*/
    

相关文章:

  • 0-Flume(1.11.0版本)在Linux(Centos7.9版本)的安装(含Flume的安装包)
  • go的限流
  • 流畅的 Python 第二版(GPT 重译)(十)
  • 常用的Node.js命令集锦
  • SOCKS5代理、代理IP、HTTP与网络安全的融合之旅
  • Linux常用操作命令(清单快查版)
  • vue3封装leaflet并使用高德底图
  • 学习次模函数-第1章 引言
  • 蓝桥杯算法基础(28)11道关于字符串的小题
  • gateway网关指定路由响应超时时间
  • C#宿舍信息管理系统
  • 基于深度学习的面部情绪识别算法仿真与分析
  • 【LAMMPS学习】三、构建LAMMPS(8)构建 LAMMPS 文档
  • 《python编程快速上手——让繁琐工作自动化》实践项目——逗号代码
  • 微信小程序多图列表页面性能问题为什么会出现?如何解决?
  • 收藏网友的 源程序下载网
  • [case10]使用RSQL实现端到端的动态查询
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Angular6错误 Service: No provider for Renderer2
  • Brief introduction of how to 'Call, Apply and Bind'
  • CSS中外联样式表代表的含义
  • golang 发送GET和POST示例
  • iOS 颜色设置看我就够了
  • Java,console输出实时的转向GUI textbox
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java基本数据类型之Number
  • markdown编辑器简评
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • React Transition Group -- Transition 组件
  • Zsh 开发指南(第十四篇 文件读写)
  • 初识MongoDB分片
  • 电商搜索引擎的架构设计和性能优化
  • 番外篇1:在Windows环境下安装JDK
  • 好的网址,关于.net 4.0 ,vs 2010
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 如何利用MongoDB打造TOP榜小程序
  • 使用权重正则化较少模型过拟合
  • 用quicker-worker.js轻松跑一个大数据遍历
  • C# - 为值类型重定义相等性
  • PostgreSQL之连接数修改
  • ​低代码平台的核心价值与优势
  • !!Dom4j 学习笔记
  • #mysql 8.0 踩坑日记
  • #每日一题合集#牛客JZ23-JZ33
  • (06)金属布线——为半导体注入生命的连接
  • (4)事件处理——(7)简单事件(Simple events)
  • (BFS)hdoj2377-Bus Pass
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (四)图像的%2线性拉伸
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET 8.0 中有哪些新的变化?
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net framework profiles /.net framework 配置
  • .Net Memory Profiler的使用举例