2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。
实现 WordFilter 类:
WordFilter(string[] words) 使用词典中的单词 words 初始化对象
f(string pref, string suff)
返回词典中具有前缀 prefix 和后缀 suff 的单词的下标
如果存在不止一个满足要求的下标,返回其中 最大的下标
如果不存在这样的单词,返回 -1 。
输入:
[“WordFilter”, “f”]
[[[“apple”]], [“a”, “e”]]。
输出:
[null, 0]。

答案2023-04-17:

大体过程如下:

1.首先定义一个 Trie 树的结点类型 TrieNode,包含 nexts 数组和 indies 切片,其中 nexts 数组用于存储子节点,indies 切片用于存储当前节点对应的单词在原单词数组中的下标。

2.然后定义 WordFilter 结构体,包含两个指向 Trie 树根节点的指针,分别用于存储正序和倒序的 Trie 树。

3.实现 Constructor 方法,接受一个字符串数组作为参数,初始化 WordFilter 对象。在该方法内部,遍历单词数组,将每个单词插入正序和倒序的 Trie 树中。

4.实现 F 方法,接受两个字符串作为前缀和后缀参数,查找并返回满足要求的单词在原单词数组中的下标。该方法内部,分别在正序和倒序 Trie 树上匹配前缀和后缀,获取包含相应前缀和后缀的单词的下标集合。然后遍历较短的下标集合,依次在较长的下标集合中二分查找,找到最大的匹配下标。如果没有找到任何匹配,返回 -1。

5.在主函数中创建 WordFilter 对象,调用 F 方法,输出结果。

时间复杂度:

  • 构造函数 Constructor 的时间复杂度为

    O

    (

    N

    L

    2

    )

    O(NL^2)

    O(NL2),其中

    N

    N

    N 是单词数组的长度,

    L

    L

    L 是单词的最大长度。

  • 查找函数 F 的时间复杂度为

    O

    (

    M

    log

    N

    )

    O(M \log N)

    O(MlogN),其中

    M

    M

    M 是相应前缀和后缀所匹配到的下标集合的大小,

    N

    N

    N 是单词数组的长度。

空间复杂度:

  • 构造函数 Constructor 的空间复杂度为

    O

    (

    N

    L

    2

    )

    O(NL^2)

    O(NL2),即正序和倒序两棵 Trie 树的总节点数。

  • 查找函数 F 的空间复杂度为

    O

    (

    1

    )

    O(1)

    O(1),只需要常量级别的空间存储中间变量。

golang代码如下:

package main

import "fmt"

type TrieNode struct {
nexts [26]*TrieNode
indies []int
} func NewTrieNode() *TrieNode {
return &TrieNode{
nexts: [26]*TrieNode{},
indies: []int{},
}
} type WordFilter struct {
preHead *TrieNode
sufHead *TrieNode
} func Constructor(words []string) WordFilter {
wf := WordFilter{
preHead: NewTrieNode(),
sufHead: NewTrieNode(),
}
for i, word := range words {
cur := wf.preHead
for _, c := range word {
path := c - 'a'
if cur.nexts[path] == nil {
cur.nexts[path] = NewTrieNode()
}
cur = cur.nexts[path]
cur.indies = append(cur.indies, i)
}
cur = wf.sufHead
for j := len(word) - 1; j >= 0; j-- {
path := word[j] - 'a'
if cur.nexts[path] == nil {
cur.nexts[path] = NewTrieNode()
}
cur = cur.nexts[path]
cur.indies = append(cur.indies, i)
}
}
return wf
} func (this *WordFilter) F(pref string, suff string) int {
var preList, sufList []int
cur := this.preHead
for i := 0; i < len(pref) && cur != nil; i++ {
cur = cur.nexts[pref[i]-'a']
}
if cur != nil {
preList = cur.indies
}
if preList == nil {
return -1
}
cur = this.sufHead
for i := len(suff) - 1; i >= 0 && cur != nil; i-- {
cur = cur.nexts[suff[i]-'a']
}
if cur != nil {
sufList = cur.indies
}
if sufList == nil {
return -1
}
small, big := preList, sufList
if len(preList) > len(sufList) {
small, big = sufList, preList
}
for i := len(small) - 1; i >= 0; i-- {
if bs(big, small[i]) {
return small[i]
}
}
return -1
} func bs(sorted []int, num int) bool {
l, r := 0, len(sorted)-1
for l <= r {
m := (l + r) / 2
midValue := sorted[m]
if midValue == num {
return true
} else if midValue < num {
l = m + 1
} else {
r = m - 1
}
}
return false
} func main() {
wordFilter := Constructor([]string{"apple"})
ans := wordFilter.F("a", "e")
fmt.Println(ans)
}

rust代码如下:

use std::collections::HashMap;
struct WordFilter {
trie: Trie,
} impl WordFilter {
fn new(words: Vec<String>) -> Self {
let mut trie = Trie::new();
for (i, word) in words.iter().enumerate() {
let w = word.to_string() + "#" + word;
for j in 0..word.len() {
let mut node = &mut trie;
for c in w[j..].chars() {
node = node.children.entry(c).or_insert(Trie::new());
node.weight = i as i32;
}
}
}
Self { trie }
} fn f(&self, pref: String, suff: String) -> i32 {
let k = suff + "#" + &pref;
let mut node = &self.trie;
for c in k.chars() {
if let Some(child) = node.children.get(&c) {
node = child;
} else {
return -1;
}
}
node.weight
}
} struct Trie {
children: HashMap<char, Trie>,
weight: i32,
} impl Trie {
fn new() -> Self {
Self {
children: HashMap::new(),
weight: 0,
}
}
} fn main() {
let mut wordFilter = WordFilter::new(vec![String::from("apple")]);
let ans = wordFilter.f(String::from("a"), String::from("e"));
println!("ans = {}", ans)
}

2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor的更多相关文章

  1. 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈 绝对值?相对值

    小结: 1. 常数时间内检索到最小元素 2.存储 存储绝对值?相对值 存储差异 3. java-ide-debug 最小栈 - 力扣(LeetCode)https://leetcode-cn.com/ ...

  2. [LeetCode] 186. Reverse Words in a String II 翻转字符串中的单词 II

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...

  3. [LeetCode] 557. Reverse Words in a String III 翻转字符串中的单词 III

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  4. [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...

  5. 2018/04/17 每日一个Linux命令 之 tar

    10天没有更新这个每日学习 linux 了,因为实在很忙,晚上还要看会其他知识. 但是也不应该给自己找理由,还是应该每天的坚持下去 -- tar 用于在 linux 解压缩/文件 这个命令下面的参数非 ...

  6. 最小栈问题:题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

    MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.get ...

  7. [LeetCode] Reverse Words in a String III 翻转字符串中的单词之三

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  8. LeetCode 557. Reverse Words in a String III (反转字符串中的单词 III)

    Given a string, you need to reverse the order of characters in each word within a sentence while sti ...

  9. LeetCode刷题:Reverse Words in a String(翻转字符串中的单词)

    题目 Given an input string, reverse the string word by word. For example, Given s = "the sky is b ...

  10. [leetcode]151. Reverse Words in a String翻转给定字符串中的单词

    Given an input string, reverse the string word by word. Example: Input: "the sky is blue", ...

随机推荐

  1. vue下拉选择select option el-cascader删除重选值的问题

    select当下拉值多的时候 以及input cascader级联选择一个值后  后面我不想要了 vue  提供了一个关键字  可以帮你全部清空 这个关键字就是:clearable

  2. Windows10系统快速安装.NET Framework3.5的方法&常见问题处理方法

    Windows10系统快速安装.NET Framework3.5的方法&常见问题处理方法 因为我的win10想了办法来禁止自动更新,就无法照正常办法安装.NET Framework3.5,解决 ...

  3. linux java 环境搭建

    java -version 是否安装 yum -y remove java-1.7.0-openjdk* yum -y install java-1.7.0-openjdk* vim /etc/pro ...

  4. DVWA-XSS (Reflected) 反射性 XSS

    反射性XSS,是非持久性,也是最常见的XSS,通过解析传入前段页面,常见为交互式输入框 LOW 审计源码 <?php // 发送请求头 header ("X-XSS-Protectio ...

  5. Python学习笔记--循环的知识以及应用

    while循环 代码: 结果: 案例:求1-100的和 实现: 案例:while循环猜数字 实现: while循环的嵌套使用 案例:打印九九乘法表 (注意:要是想要输出不换行,代码可以这样写:prin ...

  6. 阿里云镜像创建Spring Boot工厂

    参考博客:https://blog.csdn.net/qq_40052237/article/details/115794368 http://start.aliyun.com

  7. 创业团队如何落地敏捷测试,提升质量效能?丨声网开发者创业讲堂 Vol.03

    前言 老牛是资深测试专家.技术架构师.具备多年互联网公司从业经验以及十多年一线研发经验.同时也是 DevOps 践行者,近几年兼任质量团队的管理工作.其中,负责的某技术平台,稳定运行两年多,累计调用量 ...

  8. 使用dataX收获的教训

    首先是安装dataX,安装非常简单,只需下载对应的压缩包即可. 下载地址:https://github.com/alibaba/DataX 首先我出现的第一个错误:命令提示符界面出现出现乱码. 解决方 ...

  9. 解决vue中滚轮事件报错 Added non-passive event listener to a scroll-blocking 'mousewheel' event.告警

    参考:https://www.jianshu.com/p/23850d4cade8 参考:让页面滑动流畅得飞起的新特性:Passive Event Listeners

  10. ACM-NEFUOJ-P210畅通工程并查集

    题目:我已经明示到这个程度了你还不用并查集? #include<bits/stdc++.h> using namespace std; const int MAXN=1010; int F ...