LeetCode每日一题——792. 匹配子序列的单词数

简介: 给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。

题目

给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。

字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。

例如, “ace” 是 “abcde” 的子序列。

示例

示例 1:

输入: s = “abcde”, words = [“a”,“bb”,“acd”,“ace”]

输出: 3

解释: 有三个是 s的子序列的单词: “a”, “acd”, “ace”。

示例 2:

输入: s = “dsahjpjauf”, words = [“ahjpjau”,“ja”,“ahbwzgqnuk”,“tnmlanowax”]

输出: 2

提示:

1 <= s.length <= 5 * 104

1 <= words.length <= 5000

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

words[i]和 s 都只由小写字母组成。

思路

哈希表+二分查找:

传统的双指针判断是否为子序列的方法在本题会超时,思考一下,这里对字符不匹配的情况做了大量重复判断,所以采用哈希表记录下来

s中出现的字符的所有下标,在遍历words中的某个字符串word时,当我们遍历到word[i]的下一个字符word[i+1]时,我们不需要再依次从s往后匹配,我们只需要找到哈希表中键为word[i+1],值为大于i的最小值的坐标即为所求坐标(这一步骤可以使用二分查找)。

题解

class Solution:
    def numMatchingSubseq(self, s: str, words: List[str]) -> int:
      # 哈希表,存放s中字符与下标的映射
        dmap = {}
        for i, c in enumerate(s):
            if dmap.get(c):
                dmap[c].append(i)
            else:
                dmap[c] = [i]
        ans = 0
        # 遍历words
        for w in words:
          # 判断w中是否所有字符都符合规则
            ok = True
      # 判断的初始最小下标为-1
            idx = -1
            # 遍历words[i]
            for i in range(len(w)):
                idxs = dmap.get(w[i], [])
                # 二分查找
                l, r = 0, len(idxs) - 1
                while l < r :
                    mid = l + r >> 1
                    if dmap.get(w[i], [])[mid] > idx:
                        r = mid
                    else:
                        l = mid + 1
                # 未找到符合要求的下标
                if r < 0 or dmap.get(w[i], [])[r] <= idx:
                  # 判断条件为False,直接退出
                    ok = False
                    break
                # 找到符合要求的下标判断下标需要更改
                else:
                    idx = dmap.get(w[i], [])[r]
            # 若全部字符符合要求则+1,否则不变
            ans += 1 if ok else 0
        return ans
目录
相关文章
|
2月前
|
Python
【Leetcode刷题Python】376. 摆动序列
文章提供了解决LeetCode "摆动序列" 问题的Python实现代码,通过遍历整数数组并使用两个变量 down 和 up 来记录正差和负差摆动序列的长度,最终返回最长摆动子序列的长度。
32 0
|
2月前
|
算法
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
|
2月前
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
22 6
|
2月前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
17 3
|
2月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
25 4
|
2月前
|
Python
【Leetcode刷题Python】生词本单词整理
文章提供了一个Python程序,用于帮助用户整理和排版生词本上的单词,包括去除重复单词、按字典序排序,并按照特定的格式要求进行打印排版。
25 3
|
2月前
|
Python
【Leetcode刷题Python】105. 从前序与中序遍历序列构造二叉树
LeetCode上105号问题"从前序与中序遍历序列构造二叉树"的Python实现,通过递归方法根据前序和中序遍历序列重建二叉树。
18 3
|
2月前
|
算法 Python
【Leetcode刷题Python】300. 最长递增子序列
LeetCode 300题 "最长递增子序列" 的两种Python解决方案:一种使用动态规划,另一种使用贪心算法结合二分查找。
30 1
|
2月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
34 0
|
2月前
|
Python
【Leetcode刷题Python】674. 最长连续递增序列
LeetCode 674题 "最长连续递增序列" 的Python解决方案,使用动态规划算法找出给定整数数组中最长连续递增子序列的长度。
53 0