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

学习记录:js算法(六十一):添加与搜索单词 - 数据结构设计

文章目录

    • 添加与搜索单词 - 数据结构设计
      • 思路一
      • 思路二

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

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary
WordDictionary() 初始化词典对象
void addWord(word)word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 falseword 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。

输入:
["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 构造函数

  1. 初始化 Trie 结构:WordDictionary构造函数初始化一个空的字典树,根节点是一个空对象{},用于后续插入和搜索操作。

addWord 方法

  1. 遍历单词:遍历给定的单词word的每一个字符char,从根节点开始。
  2. 插入字符到 Trie:对于每一个字符,如果当前节点没有对应的子节点,则创建一个新的子节点。然后,将当前节点更新为这个子节点,继续处理下一个字符。
  3. 标记单词结束:当所有字符都处理完毕后,将最后一个节点的isWord属性设为true,表示一个单词的结束。

search 方法

  1. 调用 DFS 方法:search方法接收一个可能包含通配符.的单词,然后调用dfs方法从根节点开始进行深度优先搜索。
  2. 处理字符:对于每个字符,如果字符不是通配符.,则检查当前节点是否有对应的子节点,如果有,则递归调用dfs继续搜索;如果没有,则返回false
  3. 处理通配符:如果遇到通配符.,则遍历当前节点的所有子节点,递归调用dfs方法进行搜索,如果在任一子节点的搜索中返回true,则立即返回true

dfs 方法

  1. 结束条件:如果当前索引index等于输入单词的长度,说明已经遍历完所有字符,此时如果当前节点的isWord属性为true,则返回true,表示找到匹配的单词。
  2. 非通配符处理:如果当前字符不是通配符.,检查当前节点是否有对应的子节点,如果有,则递归调用dfs方法继续搜索,否则返回false
  3. 通配符处理:如果当前字符是通配符.,遍历当前节点的所有子节点(除了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 类

  1. children:一个对象,用于存储当前节点的所有子节点。每个子节点的键是字符,值是对应的 TrieNode 实例。
  2. isEndOfWord:一个布尔值,标记当前节点是否是一个完整单词的结束。若为 true,则表示从根节点到该节点的路径形成了一个完整的单词。

WordDictionary 类

  1. constructor():初始化 WordDictionary 类时创建一个根节点 this.root,所有单词都将从这个节点开始构建。

addWord() 方法

  1. 这个方法用于将一个新单词添加到字典中。
  2. 从根节点开始遍历单词的每个字符。
  3. 如果当前字符的子节点不存在,则创建一个新的 TrieNode
  4. 移动到当前字符的子节点,继续处理下一个字符。
  5. 最后,将最后一个节点的 isEndOfWord 属性设置为 true,表示这个节点是一个完整单词的结束。

search() 方法

  1. 这个方法用于查找字典中是否存在与给定字符串匹配的单词。它调用 _searchInNode 方法来执行实际的搜索操作。

_searchInNode() 递归搜索

  1. 这个方法是递归的核心部分,负责在 Trie 中查找与给定字符串匹配的单词。
  2. 遍历 word 的每个字符。
  3. 如果字符是 “ . ”,则需要检查当前节点的所有子节点:
    • 对每个子节点,递归调用 _searchInNode 方法,传入剩余的字符串(从 i + 1 开始)。
    • 如果在任何一个子节点中找到了匹配,返回 true
    • 如果所有子节点都没有找到匹配,返回 false
  4. 如果字符不是 “ . ”,则直接查找当前字符对应的子节点:
    • 如果子节点不存在,返回 false
    • 如果子节点存在,移动到该子节点,继续处理下一个字符。
  5. 最后,检查当前节点的 isEndOfWord 属性,返回它的值,表示是否找到了一个完整的单词。

相关文章:

学习记录:js算法(六十一):添加与搜索单词 - 数据结构设计

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

Jetpack-ObservableField实现双向绑定

ObservableField是Android Data Binding库中的一个类&#xff0c;用于实现双向绑定。双向绑定意味着当数据模型中的数据发生变化时&#xff0c;UI会自动更新&#xff1b;同时&#xff0c;当用户在UI上进行操作时&#xff0c;数据模型也会相应地更新。 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、大模型、多模态技术开发与应用研修班》都学什么内容呢&#xff1f;下面我们来看看&#xff1a; 1.了解AIGC发展现状与核心技术。 2.掌握Transformer核心开发技术。 3.掌握…...

kubernetes自定义pod启动用户

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

C4T避风型电动采光排烟天窗(图集09J621-2)

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

多态常见面试问题

1、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许同一个接口表现出不同的行为。在C中&#xff0c;多态性主要通过虚函数来实现&#xff0c;分为编译时多态&#xff08;静态多态&#xff09;和运行时多态…...

案例-登录认证(上)

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

对BSV区块链下一代节点Teranode的答疑解惑(上篇)

​​发表时间&#xff1a;2024年8月7日 2024年初BSV区块链研发团队揭晓了即将到来的Teranode更新的突破性特性&#xff0c;这些特性将显著提升网络的效率和处理速度&#xff0c;使BSV区块链能够达到百万级TPS。 Teranode的项目主管Siggi Oskarsson强调&#xff1a;“当你阅读这…...

vue父子组件传参的方法

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

关于this指针

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

机器学习西瓜书

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

如何使用 Puppeteer 和 Browserless 运行自动化测试?

Puppeteer&#xff1a;什么是 Puppeteer 及其功能 Puppeteer 是一个 Node.js 库。使用 Puppeteer&#xff0c;您可以在所有基于 Chromium 的浏览器上测试您的网站&#xff0c;包括 Chrome、Microsoft Edge Chrome 和 Chromium。此外&#xff0c;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刚开的 需要上车的扣&#xff0c;工作用 大家一起PIN分摊点压力。 在当今数字化的时代&#xff0c;程序员这一职业已经从幕后走到了前台&#xff0c;成为推动科技进步和社会变革的关键力量。编写代码、解决问题、不断学习新技术&#xff0c;程序员们的日常充满了挑战与…...

论文笔记:Pre-training to Match for Unified Low-shot Relation Extraction

论文来源&#xff1a;ACL 2022 论文地址&#xff1a;https://aclanthology.org/2022.acl-long.397.pdf 论文代码&#xff1a;https://github.com/fc-liu/MCMN &#xff08;笔记不易&#xff0c;请勿恶意转载抄袭&#xff01;&#xff01;&#xff01;&#xff09; 目录 A…...

一篇文章带你快速了解linux中关于信号的核心内容

1. 信号概念 信号是操作系统用来通知进程某个特定事件已经发生的一种方式。它们是一种软件中断&#xff0c;可以被发送到进程以对其进行异步通知。 2. 信号处理的三种方式 执行默认动作执行自定义动作忽略 signal() 函数&#xff1a;将信号处理设置为 SIG_IGN&#xff0c;可…...

openEuler、Linux操作系统常见操作-(6)如何登录Linux

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

Python基础语法条件

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

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...