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. Rancher 通过主机标签进行调度

    https://blog.csdn.net/qq12547345/article/details/121486709

  2. ubuntu添加了id_rsa.pub*authorized_keys依然不能免密登录?

    cd .ssh chmod 600 authorized_keys 还是不行,看日志 tail -f /var/log/auth.log bad ownership or modes for dire ...

  3. python之pyqt5-第一个pyqt5程序-图像压缩工具-小记

    (如想转载,请联系博主或贴上本博地址) 此为学习pyqt5的第一个程序,图像压缩工具. 因为比较简单,下面直接贴上代码. 效果图如下: # -*- coding: utf-8 -*- import s ...

  4. 【BUUCTF】ACTF2020 新生赛Include1 write up

    查看源代码+抓包都没有发现什么信息,只有这两个东东 <meta charset="utf8"> Can you find out the flag? <meta ...

  5. 第八次团队作业:Beta冲刺(凡事预则立)

    这个作业属于哪个课程 2018级计算机和综合实验班 这个作业要求在哪里 Beta冲刺要求 这个作业的目标 Beta冲刺 改进完善的功能 完善之前年度报告功能 尽快上线小程序 增加的新功能 小程序打卡功 ...

  6. JWT用户认证体系

    依赖 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifa ...

  7. linux 镜像备份

    linux 镜像备份 使用linux虚拟机的方法 优点 镜像大小比较小 缺点 速度可能比较慢 方法 1.打开虚拟机 我用的ubuntu,读卡器连接电脑虚拟机,ubuntu一般会自动挂载 df -h # ...

  8. Any to Any 实时变声的实现与落地丨RTC Dev Meetup

    前言 「语音处理」是实时互动领域中非常重要的一个场景,在「RTC Dev Meetup丨语音处理在实时互动领域的技术实践和应用」活动中,来自声网.微软和数美的技术专家,围绕该话题进行了相关分享. 本文 ...

  9. 传输层和网络层的checksum区别,TCP cksum为何包含伪首部

    一直搞不清传输层和网络层的校验和为什么校验内容不一样,最近问了一些前辈,找寻了一些答案,总结一下自己的思考. 先说一下传输层(TCP)和网络层(IP)的校验和: TCP校验和有伪首部.TCP herd ...

  10. XXL-Job与Elastic-Job详细对比

    1. 失败处理策略 失败处理策略 XXL-Job Elastic-Job 失败重试 支持,最多重试三次.重试时间间隔可配置. 支持,最多重试十次.重试时间间隔可配置. 失败告警 支持,可配置告警接收人 ...