题目
给定一个字符串 s,计算 s 的 不同非空子序列 的个数。因为结果可能很大,所以返回答案需要对 10^9 + 7 取余 。
字符串的 子序列 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。
例如,”ace” 是 “abcde” 的一个子序列,但 “aec” 不是。
示例 1:
输入:s = “abc”
输出:7
解释:7 个不同的子序列分别是 “a”, “b”, “c”, “ab”, “ac”, “bc”, 以及 “abc”。示例 2:
输入:s = “aba”
输出:6
解释:6 个不同的子序列分别是 “a”, “b”, “ab”, “ba”, “aa” 以及 “aba”。示例 3:
输入:s = “aaa”
输出:3
解释:3 个不同的子序列分别是 “a”, “aa” 以及 “aaa”。提示:
1 <= s.length <= 2000
s 仅由小写英文字母组成来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/distinct-subsequences-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
没有思路,学习一下,官解讲的很清楚,O(n)时间,见「这里」。
代码
class Solution {
public int distinctSubseqII(String s) {
int mod = (int) (1e9 + 7);
int n = s.length();
long[] dp = new long[n + 1];
dp[0] = 1;
int[] last = new int[26];
for (int i = 1; i <= n; i++) {
int index = s.charAt(i - 1) - 'a';
dp[i] = 2 * dp[i - 1] % mod;
if (last[index] > 0) {
// 可能减成负的,也要取余
dp[i] = (dp[i] - dp[last[index] - 1] + mod) % mod;
}
// 这里last中的值从1开始,省去了初始化-1
last[index] = i;
}
return (int) (dp[n] - 1);
}
}