22.10.14 字符串不同子序列计数问题

22.10.14 字符串不同子序列计数问题

   LC每日一题,很有意思的一个系列的题目,确实动态规划是一个非常难以想到的思路,但是想到以后代码真的非常简洁优美,于是不得不写一篇 blog 总结一下!

940. 不同的子序列 II

题目链接:940. 不同的子序列 II
题目大意:
给定一个字符串 s,计算 s 的 不同非空子序列 的个数。因为结果可能很大,所以返回答案需要对 10^9 + 7 取余 。
字符串的 子序列 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。
例如,“ace” 是 “abcde” 的一个子序列,但 “aec” 不是。

例如:

输入:s = "abc"
输出:7
解释:7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。

输入:s = "aba"
输出:6
解释:6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。

输入:s = "aaa"
输出:3
解释:3 个不同的子序列分别是 "a", "aa" 以及 "aaa"
  • 解题思路:非常有趣的思路,动态监视 dp 数组的和。
  • 时间复杂度: O ( N × C ) O(N\times C) O(N×C) ,N为字符串长度,C为26
  • 空间复杂度: O ( C ) O(C) O(C)
class Solution:
    def distinctSubseqII(self, s: str) -> int:
        Mod = 10**9+7
        dp = [0]*26
        for ch in s:
            dp[ord(ch)-ord('a')] = (sum(dp)+1)%Mod
        return (sum(dp))%Mod

1987. 不同的好子序列数目(加设条件)

题目链接:1987. 不同的好子序列数目
题目大意:给你一个二进制字符串 binary 。 binary 的一个 子序列 如果是 非空 的且没有 前导 0 (除非数字是 “0” 本身),那么它就是一个 好 的子序列。
请你找到 binary 不同好子序列 的数目。
比方说,如果 binary = “001” ,那么所有 好 子序列为 [“0”, “0”, “1”] ,所以 不同 的好子序列为 “0” 和 “1” 。 注意,子序列 “00” ,“01” 和 “001” 不是好的,因为它们有前导 0 。
请你返回 binary 中 不同好子序列 的数目。由于答案可能很大,请将它对 109 + 7 取余 后返回。
一个 子序列 指的是从原数组中删除若干个(可以一个也不删除)元素后,不改变剩余元素顺序得到的序列。

例如:

输入:binary = "001"
输出:2
解释:好的二进制子序列为 ["0", "0", "1"] 。
不同的好子序列为 "0""1" 。

输入:binary = "11"
输出:2
解释:好的二进制子序列为 ["1", "1", "11"] 。
不同的好子序列为 "1""11" 。

输入:binary = "101"
输出:5
解释:好的二进制子序列为 ["1", "0", "1", "10", "11", "101"] 。
不同的好子序列为 "0""1""10""11""101"
  • 解题思路:在 940. 不同的子序列 II 的基础上 加设前缀‘0’的条件。
  • 时间复杂度: O ( N ) O(N) O(N),N为字符串长度
  • 空间复杂度: O ( 1 ) O(1) O(1)
class Solution:
    def numberOfUniqueGoodSubsequences(self, s: str) -> int:
        Mod = 10**9+7
        dp = [0]*2
        for ch in s:
            if ch == '0':
                dp[0] = (sum(dp))%Mod        
            else:
                dp[1] = (sum(dp)+1)%Mod
        return (sum(dp)+('0' in s))%Mod

总结

   努力 奋斗!最近在用MATLAB 将更新几篇相关的编程,这个月不好过啊!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值