LeetCode 940. 不同的子序列 II
使用递归将导致超时。
通过分析可以知道
例:对于字符串"ab"
有子序列"a"
、"b"
和"ab"
,当出现一个新的元素c
,也就是字符串变成"abc"
的时候,相较于字符串"ab"
,子序列多出了"ac"
、"bc"
和"c"
,此时字符串"abc"
的子序列为 "a"
、"b"
、"ab"
、"ac"
、"bc"
、"abc"
和"c"
,一共为7个。
不难看出当新的元素出现的时候,会把之前子序列("a"
、"b"
和"ab"
)加上这个新元素(c
)形成新的子序列("ac"
、"bc"
和"abc"
),再与原有的子序列("a"
、"b"
和"ab"
)并加单独这个元素构成的子序列("c"
)构成新的子序列合集("a"
、"b"
、"ab"
、"ac"
、"bc"
、"abc"
和"c"
一共7个子序列),此时序列数等于之前序列数的两倍 + 1
但是如果出现的元素不是新的元素,而是在之前出现过的元素的时候,例如对于字符串"abc"
,当再一个元素为c
的时候,即字符串为"abcc"
时,原有子序列为"a"
、"b"
、"ab"
、"ac"
、"bc"
和"c"
,此时会发现对于原有子序列中有一部分("a"
、"b"
和"ab"
)在之前c
元素上一次出现的时候已经与元素c
形成了子序列("ac"
和"bc"
),因此为避免重复此时出现的元素"c"
不能与之前出现时已有的子序列("a"
、"b"
和"ab"
)形成新的子序列,只能和之后的子序列("ac"
、"bc"
、"abc"
和"c"
)组成新的子序列("acc"
、"bcc"
、"abcc"
和"cc"
),此时子序列为("a"
、"b"
、"ab"
、"ac"
、"bc"
、"abc"
、"c"
、"acc"
、"bcc"
、"abcc"
和"cc"
一共11个子序列),此时的子序列 = 现有序列数 + (现有序列数 - 上一次元素出现时的子序列数)
class Solution {
public:
int distinctSubseqII(string s) {
int res = 0;
int dir[26];
for(int i = 0; i < 26; i++)
dir[i] = -1;
for(int i = 0; i < s.size(); i++)
{
if(dir[s[i] - 'a'] == -1)
{
dir[s[i] - 'a'] = res;
res = ((res * 2) % 1000000007 + 1) % 1000000007;
}
else
{
int temp = dir[s[i] - 'a'];
dir[s[i] - 'a'] = res;
res = ((res * 2) % 1000000007 - temp) % 1000000007;
}
}
if(res < 0)
res = res + 1000000007;
return res;
}
};