LeetCode每日一题——745. 前缀和后缀搜索

简介: 设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。

题目

设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。

实现 WordFilter 类:

WordFilter(string[] words) 使用词典中的单词 words 初始化对象。

f(string pref, string suff) 返回词典中具有前缀 prefix 和后缀 suff 的单词的下标。如果存在不止一个满足要求的下标,返回其中 最大的下标 。如果不存在这样的单词,返回 -1 。

示例

输入

[“WordFilter”, “f”]

[[[“apple”]], [“a”, “e”]]

输出

[null, 0]

解释

WordFilterwordFilter=newWordFilter([“apple”]);wordFilter.f(“a”, “e”); // 返回 0 ,因为下标为 0 的单词:前缀 prefix = “a” 且 后缀 suff = “e” 。

提示:

1 <= words.length <= 104

1 <= words[i].length <= 7

1 <= pref.length, suff.length <= 7

words[i]、pref 和 suff 仅由小写英文字母组成

最多对函数 f 执行 104 次调用

思路

  1. 维护两个字典树,一个记录前缀,另一个记录后缀。这里注意:每个节点需定义一个集合变量,记录给定words中以该节点之前字符串为前缀的下标。
  2. 分别得到前缀和后缀的下标集合,二者都从后往前遍历,比较二者大小,若相等直接返回下标,前缀中坐标大则前缀往前,后缀中坐标大则后缀往前。

题解

# 字典树代码
class TireNode:
    def __init__(self):
        # 记录字符串下标
        self.id = []
        self.child = [None] * 26
    # 插入
    def insert(self, s, index, root):
        if root is None:
            return None
        for i in list(s):
            if root.child[ord(i) - ord('a')] is None:
                root.child[ord(i) - ord('a')] = TireNode()
            root = root.child[ord(i) - ord('a')]
            # 加入下标
            root.id.append(index)
    # 寻找前缀的下标集合
    def search(self, s, root):
        if root is None:
            return None
        for i in list(s):
            if root.child[ord(i) - ord('a')] is None:
                return None
            root = root.child[ord(i) - ord('a')]
        return root.id
class WordFilter:
    def __init__(self, words: List[str]):
        self.TreeQ = TireNode()
        self.TreeH = TireNode()
        # 初始化两树
        for i in range(len(words)):
            self.TreeQ.insert(words[i], i, self.TreeQ)
            self.TreeH.insert(words[i][::-1], i, self.TreeH)
    def f(self, pref: str, suff: str) -> int:
        #  分别找到前缀和后缀对应的下标集合
        Q = self.TreeQ.search(pref, self.TreeQ)
        H = self.TreeH.search(suff[::-1], self.TreeH)
        # 任意一个为空直接返回
        if H is None or Q is None:
            return -1
        l, r = len(Q) - 1, len(H) -1
        # 从后往前遍历
        while l >= 0 and r >= 0:
            if Q[l] == H[r]:
                return Q[l]
            elif Q[l] > H[r]:
                l -= 1
            else:
                r -= 1
        return -1
目录
相关文章
|
2月前
|
算法 索引
LeetCode(搜索插入位置)
如何使用二分查找算法来解决LeetCode上的“搜索插入位置”问题,确保时间复杂度为O(log n),并提供了详细的代码实现和分析。
15 2
|
2月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
23 0
Leetcode第三十三题(搜索旋转排序数组)
|
2月前
【LeetCode 39】700.二叉搜索树中的搜索
【LeetCode 39】700.二叉搜索树中的搜索
16 0
|
4月前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
4月前
|
算法
LeetCode第74题搜索二维矩阵
文章讲解了LeetCode第74题"搜索二维矩阵"的解决方案,利用二分搜索法将问题简化,并通过数学转换找到二维矩阵中的对应元素,展示了将二维问题转化为一维问题的解题技巧。
LeetCode第74题搜索二维矩阵
|
4月前
|
算法
LeetCode第35题搜索插入位置
这篇文章介绍了LeetCode第35题"搜索插入位置"的解题方法,通过使用二分查找法,高效地找到在有序数组中插入一个目标数的最佳位置。
LeetCode第35题搜索插入位置
|
4月前
|
算法
LeetCode第33题搜索旋转排序数组
这篇文章介绍了LeetCode第33题"搜索旋转排序数组"的解题方法,通过使用二分查找法并根据数组的有序性质调整搜索范围,实现了时间复杂度为O(log n)的高效搜索算法。
LeetCode第33题搜索旋转排序数组
|
4月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
50 4
|
4月前
|
算法 Python
【Leetcode刷题Python】74. 搜索二维矩阵
两种解决LeetCode "搜索二维矩阵" 问题的方法的Python实现。第一种方法是从二维矩阵的右上角开始线性搜索,通过比较当前元素与目标值来决定搜索方向。第二种方法是将二维矩阵视为一维数组进行二分查找,通过计算中间元素的行列索引来更新搜索区间。两种方法都旨在高效地判断目标值是否存在于给定的有序二维矩阵中。
45 0
|
4月前
|
算法 索引 Python
【Leetcode刷题Python】33. 搜索旋转排序数组
解决LeetCode "搜索旋转排序数组" 问题的Python实现代码。代码使用了二分查找算法,首先检查目标值是否存在于数组中,然后通过比较数组中间值与数组首尾值来确定应该在数组的哪一半继续搜索,直到找到目标值或搜索范围为空。如果找到目标值,返回其索引;如果搜索结束仍未找到,返回 -1。
20 0