学习记录:js算法(六十一):添加与搜索单词 - 数据结构设计
文章目录
- 添加与搜索单词 - 数据结构设计
- 思路一
- 思路二
添加与搜索单词 - 数据结构设计
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 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
思路一
var WordDictionary = function() {this.root = {};
};/** * @param {string} word* @return {void}*/
WordDictionary.prototype.addWord = function(word) {let node = this.root;for (let char of word) {if (!node[char]) {node[char] = {};}node = node[char];}node.isWord = true;
};/** * @param {string} word* @return {boolean}*/
WordDictionary.prototype.search = function(word) {return this.dfs(this.root, word, 0);
};WordDictionary.prototype.dfs = function(node, word, index) {const char = word[index];if (index === word.length) {return node.isWord === true;}if (char !== '.') {if (node[char] && this.dfs(node[char], word, index + 1)) {return true;}} else {for (let childChar in node) {if (childChar !== 'isWord' && this.dfs(node[childChar], word, index + 1)) {return true;}}}return false;
};
讲解
WordDictionary 构造函数
- 初始化 Trie 结构:WordDictionary构造函数初始化一个空的字典树,根节点是一个空对象{},用于后续插入和搜索操作。
addWord 方法
- 遍历单词:遍历给定的单词word的每一个字符char,从根节点开始。
- 插入字符到 Trie:对于每一个字符,如果当前节点没有对应的子节点,则创建一个新的子节点。然后,将当前节点更新为这个子节点,继续处理下一个字符。
- 标记单词结束:当所有字符都处理完毕后,将最后一个节点的isWord属性设为true,表示一个单词的结束。
search 方法
- 调用 DFS 方法:search方法接收一个可能包含通配符.的单词,然后调用dfs方法从根节点开始进行深度优先搜索。
- 处理字符:对于每个字符,如果字符不是通配符.,则检查当前节点是否有对应的子节点,如果有,则递归调用dfs继续搜索;如果没有,则返回false。
- 处理通配符:如果遇到通配符.,则遍历当前节点的所有子节点,递归调用dfs方法进行搜索,如果在任一子节点的搜索中返回true,则立即返回true。
dfs 方法
- 结束条件:如果当前索引index等于输入单词的长度,说明已经遍历完所有字符,此时如果当前节点的isWord属性为true,则返回true,表示找到匹配的单词。
- 非通配符处理:如果当前字符不是通配符.,检查当前节点是否有对应的子节点,如果有,则递归调用dfs方法继续搜索,否则返回false。
- 通配符处理:如果当前字符是通配符.,遍历当前节点的所有子节点(除了isWord属性),对每个子节点递归调用dfs方法进行搜索,如果在任一子节点的搜索中返回true,则立即返回true。
思路二
class TrieNode {constructor() {this.children = {};this.isEndOfWord = false;}
}class WordDictionary {constructor() {this.root = new TrieNode();}// 添加单词addWord(word) {let node = this.root;for (let char of word) {if (!node.children[char]) {node.children[char] = new TrieNode();}node = node.children[char];}node.isEndOfWord = true; // 标记单词的结束}// 搜索单词search(word) {return this._searchInNode(word, this.root);}// 递归搜索函数_searchInNode(word, node) {for (let i = 0; i < word.length; i++) {const char = word[i];if (char === '.') {// 如果是 '.', 遍历所有子节点for (let child in node.children) {if (this._searchInNode(word.slice(i + 1), node.children[child])) {return true;}}return false; // 如果没有匹配的子节点} else {// 如果不是 '.', 直接查找子节点if (!node.children[char]) {return false; // 如果没有这个字符,返回 false}node = node.children[char];}}return node.isEndOfWord; // 返回是否是一个完整单词}
}
讲解
TrieNode 类
- children:一个对象,用于存储当前节点的所有子节点。每个子节点的键是字符,值是对应的 TrieNode 实例。
- isEndOfWord:一个布尔值,标记当前节点是否是一个完整单词的结束。若为 true,则表示从根节点到该节点的路径形成了一个完整的单词。
WordDictionary 类
- constructor():初始化 WordDictionary 类时创建一个根节点 this.root,所有单词都将从这个节点开始构建。
addWord() 方法
- 这个方法用于将一个新单词添加到字典中。
- 从根节点开始遍历单词的每个字符。
- 如果当前字符的子节点不存在,则创建一个新的 TrieNode。
- 移动到当前字符的子节点,继续处理下一个字符。
- 最后,将最后一个节点的 isEndOfWord 属性设置为 true,表示这个节点是一个完整单词的结束。
search() 方法
- 这个方法用于查找字典中是否存在与给定字符串匹配的单词。它调用 _searchInNode 方法来执行实际的搜索操作。
_searchInNode() 递归搜索
- 这个方法是递归的核心部分,负责在 Trie 中查找与给定字符串匹配的单词。
- 遍历 word 的每个字符。
- 如果字符是 “ . ”,则需要检查当前节点的所有子节点:
- 对每个子节点,递归调用 _searchInNode 方法,传入剩余的字符串(从 i + 1 开始)。
- 如果在任何一个子节点中找到了匹配,返回 true。
- 如果所有子节点都没有找到匹配,返回 false。
- 如果字符不是 “ . ”,则直接查找当前字符对应的子节点:
- 如果子节点不存在,返回 false。
- 如果子节点存在,移动到该子节点,继续处理下一个字符。
- 最后,检查当前节点的 isEndOfWord 属性,返回它的值,表示是否找到了一个完整的单词。
相关文章:

学习记录:js算法(六十一):添加与搜索单词 - 数据结构设计
文章目录 添加与搜索单词 - 数据结构设计思路一思路二 添加与搜索单词 - 数据结构设计 请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。 实现词典类 WordDictionary : ● WordDictionary() 初始化词典对象 ● voi…...

Jetpack-ObservableField实现双向绑定
ObservableField是Android Data Binding库中的一个类,用于实现双向绑定。双向绑定意味着当数据模型中的数据发生变化时,UI会自动更新;同时,当用户在UI上进行操作时,数据模型也会相应地更新。 1.在你的项目中添加Data …...

STARnak, LTR 模型笔记
未完成. 1. 简述 CIKM 23 的一篇论文, 任务为 Learning To Rank, 输入为 候选集合, 输出为 有序列表, 用于 top-n 推荐场景. 思考: 它是要替代 ctr 预估么?它跟 mind 这种召回, 有啥大的不一样么? 2. 网络结构 u u u: 将用户(或 query) 记为 u H q d X , d Y , . . . H…...

【数据结构】:破译排序算法--数字世界的秩序密码(二)
文章目录 前言一.比较排序算法1.Bubble Sort冒泡排序1.1.冒泡排序原理1.2.冒泡排序过程1.3.代码实现1.4.复杂度和稳定性 2.Quick Sort快速排序2.1递归快速排序2.1.1.递归快速排序原理2.1.2.递归快速排序过程2.1.3.代码实现 2.2.非递归快速排序2.2.1.非递归快速排序原理2.2.2.非…...

2024年《生成式ai大模型》都学什么内容呢?
近期大家都在关注的2024 2024年10月25日 — 2024年10月29日 在成都举办的第八期《新质技术之生成式AI、大模型、多模态技术开发与应用研修班》都学什么内容呢?下面我们来看看: 1.了解AIGC发展现状与核心技术。 2.掌握Transformer核心开发技术。 3.掌握…...

kubernetes自定义pod启动用户
一、kubernetes自定义pod启动用户 一)以root用户启动pod containers:- name: ...image: ...securityContext:runAsUser: 0 二)以普通用户启动pod 1、从构建镜像角度修改 # RUN命令执行创建用户和用户组(命令创建了一个用户newuser设定ID为1…...

C4T避风型电动采光排烟天窗(图集09J621-2)
C4T避风型电动采光排烟天窗是09J621-2《电动采光排烟天窗》图集中的一种窗型。也是一种现代化的建筑消防排烟通风采光设备,被广泛应用于多风地区厂房。 C4T避风型电动采光排烟天窗配有成品避风罩,该避风置由钢制骨架和彩色钢板构成,固定在电动…...

多态常见面试问题
1、什么是多态? 多态(Polymorphism)是面向对象编程中的一个重要概念,它允许同一个接口表现出不同的行为。在C中,多态性主要通过虚函数来实现,分为编译时多态(静态多态)和运行时多态…...

案例-登录认证(上)
案例-登录认证 在前面的课程中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登 录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录 认证。 最终我…...

对BSV区块链下一代节点Teranode的答疑解惑(上篇)
发表时间:2024年8月7日 2024年初BSV区块链研发团队揭晓了即将到来的Teranode更新的突破性特性,这些特性将显著提升网络的效率和处理速度,使BSV区块链能够达到百万级TPS。 Teranode的项目主管Siggi Oskarsson强调:“当你阅读这…...

vue父子组件传参的方法
在Vue.js中,父子组件之间的参数传递是常见的需求。Vue提供了几种方法来实现这一点,主要包括使用props传递数据给子组件,以及使用事件(如自定义事件)从子组件向父组件发送数据。以下是详细的说明: 父组件向…...

关于this指针
在普通成员函数里 1.this指针不能显式说明,但能显示使用,是个常指针,只能改变指针指向的对象的内容,不能改变指针存储的对象的地址。 2.this指针一般不用特别写上,只有在(我目前的知识范围内)类…...

机器学习西瓜书
绪论 1.1绪论1.2课程定位 科学:是什么,为什么; 技术:怎么做; 工程:做的多快好省; 应用: 1.3机器学习 经典定义:利用经验改善系统自身的性能 1.4典型的机器学习过程 1.5计算学习理论 机器学习有坚实的理论基础,由Leslie Valiant的计算学习理论现在有一个数据样本x,现在…...

如何使用 Puppeteer 和 Browserless 运行自动化测试?
Puppeteer:什么是 Puppeteer 及其功能 Puppeteer 是一个 Node.js 库。使用 Puppeteer,您可以在所有基于 Chromium 的浏览器上测试您的网站,包括 Chrome、Microsoft Edge Chrome 和 Chromium。此外,Puppeteer 可用于网页抓取、自动…...

python菜鸟知识
去除空格 str 这是 含 空格 print(f去除两端空格{str.strip()}) print(f去除左端空格{str.lstrip()}) print(f去除右端空格{str.rstrip()}) print(f去除全部空格{str.replace(" ", "")}) 方法返回对象yield yield :.join([ip, port])yield {ranking…...

GPT4o,GPTo1-preview, 拼
兄弟们GPT刚开的 需要上车的扣,工作用 大家一起PIN分摊点压力。 在当今数字化的时代,程序员这一职业已经从幕后走到了前台,成为推动科技进步和社会变革的关键力量。编写代码、解决问题、不断学习新技术,程序员们的日常充满了挑战与…...

论文笔记:Pre-training to Match for Unified Low-shot Relation Extraction
论文来源:ACL 2022 论文地址:https://aclanthology.org/2022.acl-long.397.pdf 论文代码:https://github.com/fc-liu/MCMN (笔记不易,请勿恶意转载抄袭!!!) 目录 A…...

一篇文章带你快速了解linux中关于信号的核心内容
1. 信号概念 信号是操作系统用来通知进程某个特定事件已经发生的一种方式。它们是一种软件中断,可以被发送到进程以对其进行异步通知。 2. 信号处理的三种方式 执行默认动作执行自定义动作忽略 signal() 函数:将信号处理设置为 SIG_IGN,可…...

openEuler、Linux操作系统常见操作-(6)如何登录Linux
如何登录Linux Linux登陆方式主要有如下两种: 。本地登陆 。一个典型的Linux系统将运行六个虚拟控制台和一个图形控制台,openEuler目前暂未支持图形化界面; 可以通过CtrlAltF[1-6]在6个虚拟控制台之间进行切换。 远程登录 。默认情况下openEuler支持远程登录&…...

Python基础语法条件
注释 注释的作用 通过用自己熟悉的语言,在程序中对某些代码进行标注说明,这就是注释的作用,能够大大增强程序的可读性。 注释的分类及语法 注释分为两类:单行注释 和 多行注释。 单行注释 只能注释一行内容,语法如下…...

006-MAVEN 的使用
MAVEN 的使用 一、依赖范围二、依赖的传递性三、依赖的原则四、依赖的排除 一、依赖范围 在引入log4j 依赖的时候,有一个scope设置,这个scope设置的值就是对应的依赖范围(因为compile 是默认的依赖范围,所以有时也可以省略)。 Maven 提供了…...

npm使用时报错:Could not retrieve https://npm.taobao.org/mirrors/node/index.json.
在使用npm时报错,报错信息如下: 报错的原因:是原来的淘宝镜像地址过期了 解决办法:修改镜像地址。打开nvm的安装地址 -->settings.txt文件 -->配置下载源 1、将settings.txt文件中的 node_mirror: https://npm.taobao.or…...

软考中级网络工程师——高级配置
文章目录 IS-ISBGP(边境网关协议)-IBGP-EBGP配置BFD(双向转发侦测)与Router-Static联动BFD与OSPF联动BFD与VRRP(虚拟路由器冗余协议)联动VRRP配置(基于网关备份)FW基础配置FW高级配置DHCP路由策略 IS-IS 第一步:每一个路由设置环回口地址 第二部:配置接…...

Leetcode 第 141 场双周赛题解
Leetcode 第 141 场双周赛题解 Leetcode 第 141 场双周赛题解题目1:3314. 构造最小位运算数组 I思路代码复杂度分析 题目2:3315. 构造最小位运算数组 II思路代码复杂度分析 题目3:3316. 从原字符串里进行删除操作的最多次数思路代码复杂度分析…...

Linux性能调优,还可以从这些方面入手
linux是目前最常用的操作系统,下面是一些常见的 Linux 系统调优技巧,在进行系统调优时,需要根据具体的系统负载和应用需求进行调整,并进行充分的测试和监控,以确保系统的稳定性和性能。同时,调优过程中要谨…...

STM32的独立看门狗定时器(IWDG)技术介绍
在嵌入式系统中,确保系统的稳定性和可靠性至关重要。看门狗定时器(Watchdog Timer, WDT) 是一种常用的硬件机制,用于监控系统的运行状态,防止系统因软件故障或意外情况进入不可预期的状态。STM32系列微控制器提供了两种…...

自动化生成工作流?英伟达提出ComfyGen:通过LLM来匹配给定的文本提示与合适的工作流程
ComfyGen的核心在于通过LLM来匹配给定的文本提示与合适的工作流程。该方法从500个来自用户的多样化提示生成图像,随后使用一系列美学预测模型对生成结果进行评分。这些评分与相应的工作流程形成了一个训练集,包含提示、工作流程及其得分的三元组。 然后…...

indicatorTree-v10练习(有问题)
目标:设计数据库表表格式,将“indicatorTree-v10.json”导入到数据库,再从数据库读取写为JSON文件。 其他要求:数据库要求为mysql数据库;编程语言暂时限定为C;JSON解析使用本文件夹中的cJSON.c和cJSON.h&am…...

python源码:指定麦克风/音响播放歌曲
前言 我使用pygame实现了指定麦克风/音响播放歌曲的功能,主要目的是解决直播过程的多源声道控制问题。 代码 # 查看自己的音频设备 # 请记住目标音频设备的具体名称 import pygame as mixer import pygame._sdl2 as sdl2mixer.init() # Initialize the mixer, thi…...

基于华为云智慧生活生态链设计的智能鱼缸
一. 引言 1.1 项目背景 随着智能家居技术的发展和人们对高品质生活的追求日益增长,智能鱼缸作为一种结合了科技与自然美的家居装饰品,正逐渐成为智能家居领域的新宠。本项目旨在设计一款基于华为云智慧生活生态链的智能鱼缸,它不仅能够提供…...