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 将更新几篇相关的编程,这个月不好过啊!