Leetcode-每日一题792. 匹配子序列的单词数(分桶)

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/weixin_46618592/article/details/127898403?spm=1001.2014.3001.5501

在这里插入图片描述
题目链接:https://leetcode.cn/problems/number-of-matching-subsequences/description/

思路

方法一、分桶

题目意思:给你一个字符串 s 和字符串数组 words, 可以对字符串 s 某些位置上的字符进行删除,并不改变原来的字符顺序产生的子序列,去对比字符串数组 words 存在多少相同的数量。

我原本的思路是通过去重+暴力,发现卡在41的样例超时了,发现了一个问题,有很多字符串不需要去判断,大大浪费了时间,那我们去找那些我们需要的不就行了,通过对字符串数组 words 中每个字符串的首字母,放入桶内:

a:["a","acd","ace"]
b:["bb"]

遍历字符串的字符,去消除对应桶内的字符串,去生成新的桶,例如字符串 s = "abcde",我们读取到第一个字符 a 时,可以去直接处理桶a,得到的结果:

a:[]
b:["bb"]
c:["cd","ce"]

通过上述操作,我们不断获得新的桶,直到字符串 s 遍历完,真正的子序列也会被筛选啊出来。

有个问题,我们怎么统计答案呢?很简单我们只需要去判断当前桶内的字符串长度已经等于 1 的时候,我们这个字符串就是字符串 s 的子序列。

代码示例

func numMatchingSubseq(s string, words []string) (ans int) {
    ton := [26][]string{}
    for _, w := range words {
        ton[w[0] - 'a'] = append(ton[w[0] - 'a'], w)
    }
    for _, c := range s {
        q := ton[c - 'a']
        ton[c - 'a'] = nil
        for _, t := range q {
            if len(t) == 1 {
                ans++
            }else {
                ton[t[1] - 'a'] = append(ton[t[1] - 'a'], t[1:])
            }
        }
    }
    return
}

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n+ sum∣w i​∣),其中 n 和 m 分别为 s 和 words 的长度,而 ∣wi 为 words[i] 的长度,遍历一次字符串s需要O(n)的时间,sum∣w i​∣ 是 $$\sum_{i=0}^m∣w i​$$,分桶需要O(sum∣w i​∣)的时间。
  • 空间复杂度:O(m),其中 m 是 words 的长度
目录
相关文章
|
Python
【Leetcode刷题Python】376. 摆动序列
文章提供了解决LeetCode "摆动序列" 问题的Python实现代码,通过遍历整数数组并使用两个变量 down 和 up 来记录正差和负差摆动序列的长度,最终返回最长摆动子序列的长度。
101 0
|
11天前
|
存储 C++ 索引
最长连续序列(每天刷力扣hot100系列)
本题使用哈希表法求最长连续序列。利用unordered_set存储去重元素,遍历集合时仅当num-1不存在时才作为起点向后扩展,统计连续长度,时间复杂度O(n),空间复杂度O(n)。相比unordered_map更高效,因无需存储值。
|
4月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
145 1
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
127 6
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
87 3
|
Python
【Leetcode刷题Python】105. 从前序与中序遍历序列构造二叉树
LeetCode上105号问题"从前序与中序遍历序列构造二叉树"的Python实现,通过递归方法根据前序和中序遍历序列重建二叉树。
120 3
|
算法 Python
【Leetcode刷题Python】300. 最长递增子序列
LeetCode 300题 "最长递增子序列" 的两种Python解决方案:一种使用动态规划,另一种使用贪心算法结合二分查找。
109 1
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
131 0
|
Python
【Leetcode刷题Python】674. 最长连续递增序列
LeetCode 674题 "最长连续递增序列" 的Python解决方案,使用动态规划算法找出给定整数数组中最长连续递增子序列的长度。
190 0
|
存储
力扣-2904最短且字典序最小的美丽子序列
力扣-2904最短且字典序最小的美丽子序列
138 1