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

Leetcode211. 添加与搜索单词 - 数据结构设计

题目描述:

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。

示例:

输入:
[“WordDictionary”,“addWord”,“addWord”,“addWord”,“search”,“search”,“search”,“search”]
[[],[“bad”],[“dad”],[“mad”],[“pad”],[“bad”],[“.ad”],[“b…”]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord(“bad”);
wordDictionary.addWord(“dad”);
wordDictionary.addWord(“mad”);
wordDictionary.search(“pad”); // 返回 False
wordDictionary.search(“bad”); // 返回 True
wordDictionary.search(“.ad”); // 返回 True
wordDictionary.search(“b…”); // 返回 True

提示:

1 <= word.length <= 25
addWord 中的 word 由小写英文字母组成
search 中的 word 由 ‘.’ 或小写英文字母组成
最多调用 104 次 addWord 和 search

解题思路

根据题意,WordDictionary\texttt{WordDictionary}WordDictionary 类需要支持添加单词和搜索单词的操作,可以使用字典树实现。

对于添加单词,将单词添加到字典树中即可。

对于搜索单词,从字典树的根结点开始搜索。由于待搜索的单词可能包含点号,因此在搜索过程中需要考虑点号的处理。对于当前字符是字母和点号的情况,分别按照如下方式处理:

如果当前字符是字母,则判断当前字符对应的子结点是否存在,如果子结点存在则移动到子结点,继续搜索下一个字符,如果子结点不存在则说明单词不存在,返回 false\text{false}false;

如果当前字符是点号,由于点号可以表示任何字母,因此需要对当前结点的所有非空子结点继续搜索下一个字符。

重复上述步骤,直到返回 false\text{false}false 或搜索完给定单词的最后一个字符。

如果搜索完给定的单词的最后一个字符,则当搜索到的最后一个结点的 isEnd\textit{isEnd}isEnd 为 true\text{true}true 时,给定的单词存在。

特别地,当搜索到点号时,只要存在一个非空子结点可以搜索到给定的单词,即返回 true\text{true}true。

代码实现

public class WordDictionary {public class TrieNode {public TrieNode[] children = new TrieNode[26];public String item = "";}private TrieNode root = new TrieNode();public void addWord(String word) {TrieNode node = root;for (char c : word.toCharArray()) {if (node.children[c - 'a'] == null) {node.children[c - 'a'] = new TrieNode();}node = node.children[c - 'a'];}node.item = word;}public boolean search(String word) {return match(word.toCharArray(), 0, root);}private boolean match(char[] chs, int k, TrieNode node) {if (k == chs.length) return !node.item.equals("");if (chs[k] != '.') {return node.children[chs[k] - 'a'] != null && match(chs, k + 1, node.children[chs[k] - 'a']);} else {for (int i = 0; i < node.children.length; i++) {if (node.children[i] != null) {if (match(chs, k + 1, node.children[i])) {return true;}}}}return false;}
}

相关文章:

  • 【机器学习 复习】第3章 K-近邻算法
  • JavaWeb——Mysql的启动/登录/卸载
  • Netty中的Reactor模型实现
  • 什么是ETL?
  • 内容安全复习 3 - 深度学习基础
  • 数据仓库之Hive
  • Function Calling, ReAct, 以及插件机制的区别与应用
  • Lambda 表达式是为了解决啥问题,语法,使用规则,c++中的常用用法示例
  • JVS开源底座与核心引擎的全方位探索,助力IT智能、高效、便捷的进化
  • ffmpeg windows系统详细教程
  • Android集成mapbox教程
  • 向量数据库选型
  • 数据加密两大政企实践案例 | 麒麟信安护航海量核心数据安全无虞
  • 搞IT需不需要考个软考中级?
  • SQL新手蜕变:掌握这20条常用SQL语句,让你也能成为高手!
  • SegmentFault for Android 3.0 发布
  • Akka系列(七):Actor持久化之Akka persistence
  • eclipse的离线汉化
  • Java比较器对数组,集合排序
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • pdf文件如何在线转换为jpg图片
  • Promise初体验
  • V4L2视频输入框架概述
  • Vue实战(四)登录/注册页的实现
  • Webpack 4x 之路 ( 四 )
  • Webpack入门之遇到的那些坑,系列示例Demo
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 蓝海存储开关机注意事项总结
  • 前端面试题总结
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 一些css基础学习笔记
  • 用jquery写贪吃蛇
  • 原生js练习题---第五课
  • 你对linux中grep命令知道多少?
  • 《码出高效》学习笔记与书中错误记录
  • Linux权限管理(week1_day5)--技术流ken
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #面试系列-腾讯后端一面
  • (1)(1.9) MSP (version 4.2)
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (2)MFC+openGL单文档框架glFrame
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (实战篇)如何缓存数据
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)appium-desktop定位元素原理
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转) 深度模型优化性能 调参
  • (转)linux 命令大全
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)大道至简,职场上做人做事做管理
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树