题目:
给定一个字符串 S,计算 S 的不同非空子序列的个数。 因为结果可能很大,所以返回答案模 10^9 + 7.
示例 1:
输入:"abc"
输出:7 解释:7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。
示例 2:
输入:"aba"
输出:6 解释:6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。
示例 3:
输入:"aaa"
输出:3 解释:3 个不同的子序列分别是 "a", "aa" 以及 "aaa"。
解题
分析 但所有字母都不重复时 长度为i 的子序列(包括‘’空子序列)数 dp[i] = dp[i-1]*2
dp[1] = 2
dp[2] = 4
dp[3] = 8
得到状态转移方程就可以,进行解题了,处理边界和异常情况就好了。
class Solution {
public int distinctSubseqII(String S) {
int MOD = 1_000_000_007;
int N = S.length();
int[] dp = new int[N+1];
dp[0] = 1;
int[] last = new int[26];//简单的hash表 记录是否重复出现
Arrays.fill(last, -1);
for (int i = 0; i < N; ++i) {
int x = S.charAt(i) - 'a';
dp[i+1] = dp[i] * 2 % MOD;
if (last[x] >= 0) // -1 未出现 >0 表示已经在last[x]位置上出现过
dp[i+1] -= dp[last[x]]; // 消除重复出
dp[i+1] %= MOD;
last[x] = i; // 记录上次出现的位置
}
dp[N]--; // 去除空
if (dp[N] < 0) dp[N] += MOD;
return dp[N];
}
}