LeetCode-题目整理【9】:Trie树

最长公共前缀可以使用字典树来解答,在解答中,需要查找单词,如果有精确需要查找的单词word,那么可以使用代码:

func (this *Trie) Search(word string) bool {for _, v := range word {if this.next[v-'a'] == nil {return false}this = this.next[v-'a']}if this.isEnd == false {return false}return true
}

但是如果查找的单词不明确,那么可以使用代码(以公共前缀为例):

func (node *TrieNode) search() string {prefix := ""for node.countChildren() == 1 && !node.isEnd {//就是这个位置,可以遍历字典树中的字母,如果当前字母不为空,可以继续往下遍历for i := 0; i < 26; i++ {if node.next[i] != nil {prefix = prefix + string('a'+ i)node = node.next[i]break}}}return prefix
}// 计算当前节点子节点的数量
func (node *TrieNode) countChildren() int {......
}
  1. 最长公共前缀
    简单
    编写一个函数来查找字符串数组中的最长公共前缀。
    如果不存在公共前缀,返回空字符串 “”。
    示例 1:
    输入:strs = [“flower”,“flow”,“flight”]
    输出:“fl”
    示例 2:
    输入:strs = [“dog”,“racecar”,“car”]
    输出:“”
    解释:输入不存在公共前缀。
//字符串
// 函数首先找到长度最短的字符串,然后逐个比较字符,如果遇到不相同的字符,则返回当前索引之前的字符串作为结果。
//这是一个更简洁的实现,它的时间复杂度是O(n*m),其中n是字符串数组的长度,m是字符串的平均长度。func longestCommonPrefix(strs []string) string {if len(strs) == 0 {return ""}minstr := strs[0]for _, str := range strs {if len(str) < len(minstr) {minstr = str}}for i := 0; i < len(minstr); i++ {curStr := strs[0][i]for _, str := range strs {if str[i] != curStr {return strs[0][:i]}}}return strs[0][:len(minstr)]
}
//使用字典树
type TrieNode struct {next  [26]*TrieNodeisEnd bool
}func longestCommonPrefix(strs []string) string {root := &TrieNode{}//构建字典树for _, str := range strs {root.Insert(str)}//查找最长公共前缀return root.search()
}// 插入字符
func (node *TrieNode) Insert(word string) {for _, v := range word {if node.next[v-'a'] == nil {node.next[v-'a'] = &TrieNode{}}node = node.next[v-'a']}node.isEnd = true
}//查找字符和公共前缀
func (node *TrieNode) search() string {prefix := ""//当前节点的子节点数量为1(如果大于1,表示节点之后会有分叉,就不是公共节点)//且当前节点不是一个单词的结束节点,就继续循环。for node.countChildren() == 1 && !node.isEnd {for i := 0; i < 26; i++ {if node.next[i] != nil {prefix = prefix + string('a'+ i)node = node.next[i]break}}}return prefix
}// 计算当前节点子节点的数量
func (node *TrieNode) countChildren() int {count := 0for i := 0; i < 26; i++ {if node.next[i] != nil {count++}}return count
}
  1. 实现 Trie (前缀树)
    中等
    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
type Trie struct {next  [26]*TrieisEnd bool
}func Constructor() Trie {return Trie{}
}func (this *Trie) Insert(word string) {for _, v := range word {if this.next[v-'a'] == nil {this.next[v-'a'] = new(Trie)}this = this.next[v-'a']}this.isEnd = true
}func (this *Trie) Search(word string) bool {for _, v := range word {if this.next[v-'a'] == nil {return false}this = this.next[v-'a']}if this.isEnd == false {return false}return true
}//前提是已经知道 prefix 这个单词,因此和前面“查找公共前缀”的解答不一样,遍历过程不一样,(和开头中提到的精确到具体单词类似)
func (this *Trie) StartsWith(prefix string) bool {for _, v := range prefix {if this.next[v-'a'] == nil {return false}this = this.next[v-'a']}return true
}/*** Your Trie object will be instantiated and called as such:* obj := Constructor();* obj.Insert(word);* param_2 := obj.Search(word);* param_3 := obj.StartsWith(prefix);*/

下面这道题解答过程和 “实现 Trie (前缀树)” 的insert和search基本一样,主要区别在于查找单词时,多了条件:word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。
多添加的代码是判断"."的情况:

if char == '.' {for _, v := range this.next {if v != nil && v.search(word, i+1) {return true}}return false}
  1. 添加与搜索单词 - 数据结构设计
    中等
    请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
    实现词典类 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
type WordDictionary struct {next  [26]*WordDictionaryisEnd bool
}func Constructor() WordDictionary {return WordDictionary{}
}func (this *WordDictionary) AddWord(word string) {for _, v := range word {if this.next[v-'a'] == nil {this.next[v-'a'] = new(WordDictionary)}this = this.next[v-'a']}this.isEnd = true
}func (this *WordDictionary) Search(word string) bool {return this.search(word, 0)
}func (this *WordDictionary) search(word string, index int) bool {for i := index; i < len(word); i++ {char := word[i]//多了判断"."的情况,其他基本一致if char == '.' {for _, v := range this.next {if v != nil && v.search(word, i+1) {return true}}return false}if this.next[char-'a'] == nil {return false}this = this.next[char-'a']}if this.isEnd == false {return false}return true
}/*** Your WordDictionary object will be instantiated and called as such:* obj := Constructor();* obj.AddWord(word);* param_2 := obj.Search(word);*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core WebAPI从HTTPS调整为HTTP启动

使用VS2022创建WebAPI项目时&#xff0c;默认勾选“配置HTTPS(H)”&#xff0c;这样启动WebAPI时以https方式启动。   如果要从HTTPS调整为HTTP启动&#xff0c;需要修改项目中以下几处&#xff0c;首先是Program.cs中删除app.UseHttpsRedirection()语句&#xff0c;删除后…

【Unity】粒子贴图异常白边问题

从PS制作的黑底&#xff0c;白光的贴图。放入Unity粒子中&#xff0c;拉远看会有很严重的白边&#xff0c;像马赛克一样。 材质使用&#xff1a;Mobile/Particles/Additive 经测试只使用一张黑色的图片&#xff0c;也会有白边。 解决方案&#xff1a; 关闭黑色底&#xf…

php基础学习之整型进制

不同进制的整型数据定义 在 PHP中提供了四种整型的定义方式&#xff1a;十进制定义&#xff0c;二进制定义&#xff0c;八进制定义和十六进制。 定义格式如下&#xff1a; 十进制是最基础的&#xff1a;$a 110;二进制需要在值前面加上0b&#xff1a;$a 0B1101110;&#xf…

PHP AES加解密系列

PHP AES加密 使用PHP内置的mcrypt扩展库可以轻松地实现AES加密。 <?php function aes_encrypt($data, $key, $iv) {$cipher mcrypt_module_open(MCRYPT_RIJNDAEL_128, , MCRYPT_MODE_CBC, );mcrypt_generic_init($cipher, $key, $iv);$encrypted mcrypt_generic($ciphe…

arcgis 面要素shp数据处理

面要素是工作中用到最多的&#xff0c;那么面要素是如何形成的呢&#xff0c;主要还是由闭合的线要素转换而成。在面要素数据中常用的有以下几点&#xff1a; 一、 线转面&#xff08;要素转面&#xff09; 通过上一篇得到了点转线的要素&#xff0c;那么根据上节的线要素&am…

Sqlite真空命令VACUUM

之前在项目中使用了sqlite数据库&#xff0c;当日志变大时&#xff0c;执行CRUD操作就会变慢 后来尝试删除7天前的记录进行优化 delete from XX_CollectData where CreateTime<2024-01-24 发现sqlite文件的大小就没有变化&#xff0c;delete命令只是逻辑删除&#xff0c;…

BPM、低代码和人工智能:实现灵活、创新与转型的关键结合

随着零售业格局的不断演变&#xff0c;零售商正被迫在一个日益活跃、竞争日益激烈的客户驱动型市场中展开竞争。随着互联网上产品信息和评论的出现&#xff0c;消费者的态度发生了巨大的变化——购物者不再依赖销售人员来获取信息。他们现在知道的和许多零售销售人员一样多&…

Element-Plus如何实现表单校验和表单重置

一&#xff1a;页面布局介绍&#xff1a; 这是我刚刚用基于vue3element-plus写好的一个部门管理的页面 基本的增删改查已经写好&#xff0c;下面我只提供页面的template和style的代码&#xff1a; template <template><el-card class"box-card"><…

openGauss学习笔记-207 openGauss 数据库运维-常见故障定位案例-btree 索引故障情况下应对策略

文章目录 openGauss学习笔记-207 openGauss 数据库运维-常见故障定位案例-btree 索引故障情况下应对策略207.1 btree 索引故障情况下应对策略207.1.1 问题现象207.1.2 原因分析207.1.3 处理办法 openGauss学习笔记-207 openGauss 数据库运维-常见故障定位案例-btree 索引故障情…

洛谷P5735 【深基7.例1】距离函数(C语言)

首先&#xff0c;三角形周长为 其次(x1,x2)和 &#xff08;y1,y2&#xff09;的距离 然后就可以为所欲为 #include <stdio.h> #include <math.h>double distance(double a1, double b1, double a2, double b2) {return sqrt((a1 - a2) * (a1 - a2) (b1 - b2) * …

【跳槽面试】Redis的过期键删除策略?

前言 key的生存时间到了&#xff0c;Redis会立即删除吗&#xff1f;不会立即删除。 过期策略 • 定时删除&#xff1a;在设置key的过期时间的同时&#xff0c;为该key创建一个定时器&#xff0c;让定时器在key的过期时间来临时&#xff0c;对key进行删除 • 定期删除&#xff…

简单模拟实现一个线程池

废话不多说之间上代码 import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue;public class MyThreadPoolExecutor {private List<Thread> listnew ArrayList<>();pri…

qemu使用

百度qemu bios 失败 问题 坑爹的玩意&#xff0c;编译qemu 还需要python3.5以上 解决方法&#xff1a; CentOS7安装Python3.8-CSDN博客 https://www.cnblogs.com/Oliver.net/p/7211967.html 编译python3.8还由于openssl过低 成功启动qemu 先阅读官网 Download QEMU …

【Linux】Ubuntu的gnome切换KDE Plasma

文章目录 安装KDE Plasma桌面环境添加软件源并更新apt安装kubuntu-desktop&#xff08;作者没有成功&#xff09;aptitude安装kubuntu-desktop多次aptitude install&#xff08;特别重要特别重要&#xff09;其他kde软件包 卸载gnome桌面 Ubuntu自带的桌面环境是gnome&#xff…

Acwing---788.逆序对的数量

逆序对的数量 1.题目2.基本思想3.代码实现 1.题目 给定一个长度为 n n n 的整数数列&#xff0c;请你计算数列中的逆序对的数量。逆序对的定义如下&#xff1a;对于数列的第 i i i个和第 j j j 个元素&#xff0c;如果满足 i < j i<j i<j 且 a [ i ] > a [ j …

基于云原生技术栈构建企业统一基础技术平台(总纲)

一、概述 本文主要介绍基于云原生技术栈建设企业技术平台的总纲&#xff0c;该技术平台对业务应用全生命周期进行管理和支撑&#xff0c;提供从需求交付、生产运行、稳定保障、资产运营&#xff0c;以及安全生产的体系化解决方案&#xff0c;为企业自建或采购技术平台提供参考。…

【嵌入式学习】C++QT-Day2-C++基础

笔记 见我的博客&#xff1a;https://lingjun.life/wiki/EmbeddedNote/19Cpp 作业 自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度…

day02 有序数组平方、长度最小的子数组、螺旋矩阵II

题目链接&#xff1a;leetcode977-有序数组平方&#xff0c;leetcode209-长度最小的子数组, leetcode59-螺旋矩阵II 有序数组平方 解题思路&#xff1a;双指针法&#xff0c;left, right 1&#xff09;创建一个等长的新数组 2&#xff09;left从左到右扫描数组&#xff0c;ri…

【卡梅德生物】稳定细胞系构建|构建流程

在生物技术领域&#xff0c;稳定细胞系的构建是研究、药物开发和生产过程中关键的一环。稳定细胞系不仅为基因表达提供了可靠的平台&#xff0c;还在生物制药、基因治疗等领域发挥着重要作用。本文将介绍稳定细胞系构建的背景、主要类型、构建流程、技术优势&#xff0c;并强调…

考研机试 手机键盘

考研机试手机键盘 用到map工具 具体键入规则和花费时间如下描述&#xff1a; 对于同一键上的字符&#xff0c;例如 a,b,c都在 “1” 键上&#xff0c;输入 a 只需要按一次&#xff0c;输入 c需要连续按三次。 如果连续两个字符不在同一个按键上&#xff0c;则可直接按&#…