2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor
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的更多相关文章
- 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈 绝对值?相对值
小结: 1. 常数时间内检索到最小元素 2.存储 存储绝对值?相对值 存储差异 3. java-ide-debug 最小栈 - 力扣(LeetCode)https://leetcode-cn.com/ ...
- [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 ...
- [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 ...
- [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 ...
- 2018/04/17 每日一个Linux命令 之 tar
10天没有更新这个每日学习 linux 了,因为实在很忙,晚上还要看会其他知识. 但是也不应该给自己找理由,还是应该每天的坚持下去 -- tar 用于在 linux 解压缩/文件 这个命令下面的参数非 ...
- 最小栈问题:题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.get ...
- [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 ...
- 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 ...
- LeetCode刷题:Reverse Words in a String(翻转字符串中的单词)
题目 Given an input string, reverse the string word by word. For example, Given s = "the sky is b ...
- [leetcode]151. Reverse Words in a String翻转给定字符串中的单词
Given an input string, reverse the string word by word. Example: Input: "the sky is blue", ...
随机推荐
- MySql分库分表以及相关问题
为什么要分库分表? MySql是存在瓶颈的,数据量就是他最大的瓶颈,如果一张表或者一个数据库里面的数据量过大都会导致一些意料之外的问题,譬如查询过慢,难以维护等问题,这时候就要想出一个完美的解决办法. ...
- 记一个快捷在线接口YAPI
在线地址:http://192.168.252.152:3000 1.idea中file下setting中plugins搜索并加载插件YAPI 2.idea中的.idea中.misc.xml文件配置. ...
- 基于Centos7 minimal 加固
一.用户帐号和环境-----------------------. 2 二.系统访问认证和授权--------------------- 3 三.核心调整--------------------- 4 ...
- wxml2canvas爬坑之路
效果图: 前提: 公司要求生成一分报告并转为图片并保存,之前用canvas画过,但这次是在不想用canvas一点点画了,再往上找了n久,爬了n多坑,终于搞出来了 插件: wxml2canvas 一:下 ...
- 使用K8S进行蓝绿部署的简明实操指南
在之前的应用部署系列文章里,我们已经介绍过什么是蓝绿部署.如需回顾,点击下方文章链接即可重温.本文我们将会介绍如何使用 Kubernetes 实现蓝绿部署. 应用部署初探:3个主要阶段.4种常见模式 ...
- IO流详解及常用方法
1.1. 什么是IO流 IO流: Input/Output Stream 流: 指的是一串流动的数据, 在数据在流中按照指定的方向进行流动. 实现数据的读取.写入的功能. 1.2. IO流的使用场景 ...
- IntelliJ IDEA 下载安装及配置使用教程(图文步骤详解)
前言 壹哥在前面的文章中,带大家下载.安装.配置了Eclipse这个更好用的IDE开发工具,并教会了大家如何在Eclipse中进行项目的创建和代码编写.运行.但是实际上,在各种IDE开发工具中,Ecl ...
- Oracle 函数整理
一.字符控制函数 函数 结果 CONCAT('Hello','World') HelloWorld SUBSTR('HelloWorld',1,5) Hello LENGTH('HelloWorld' ...
- volatile 关键字(轻量级同步机制)
更多内容,前往IT-BLOG volatile 表示 "不稳定" 的意思.用于修饰共享可变变量,即没有使用 final(不可变变量) 关键字修饰的实例变量或静态变量,相应的变量就被 ...
- Promise合集
Promise.all Promise.all 可以将多个 Promise 实例包装成一个新的 Promise 实例.所有的 Promise 对象都成功时返回的是一个结果数组,一旦有任何一个 Prom ...