Given a string s, return the number of distinct non-empty subsequences ofs. Since the answer may be very large, return it modulo109 + 7.
A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., "ace" is a subsequence of "abcde" while "aec" is not.
Every new character can be added to all existing subsequences to form new ones, but we must avoid double-counting subsequences that end with the same character seen before.
Let dp[i] be the number of distinct subsequences for the prefix of length i.
For each character, double the count (add the character to all previous subsequences), but subtract the count from the last time this character appeared.
Use an array to track the last position of each character.
Return dp[n] - 1 (subtract the empty subsequence).
classSolution {
publicintdistinctSubseqII(String s) {
int n = s.length(), mod = 1000000007;
int[] dp =newint[n+1]; dp[0]= 1;
int[] last =newint[26]; Arrays.fill(last, -1);
for (int i = 0; i < n; ++i) {
dp[i+1]= (2 * dp[i]) % mod;
int c = s.charAt(i) -'a';
if (last[c]!=-1) dp[i+1]= (dp[i+1]- dp[last[c]]+ mod) % mod;
last[c]= i;
}
return (dp[n]- 1 + mod) % mod;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution {
fundistinctSubseqII(s: String): Int {
val n = s.length
val mod = 1_000_000_007
val dp = IntArray(n+1); dp[0] = 1val last = IntArray(26) { -1 }
for (i in0 until n) {
dp[i+1] = (2L * dp[i] % mod).toInt()
val c = s[i] - 'a'if (last[c] != -1) dp[i+1] = (dp[i+1] - dp[last[c]] + mod) % mod
last[c] = i
}
return (dp[n] - 1 + mod) % mod
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defdistinctSubseqII(self, s: str) -> int:
n, mod = len(s), 10**9+7 dp = [1] + [0]*n
last = [-1]*26for i, ch in enumerate(s):
dp[i+1] =2* dp[i] % mod
c = ord(ch) - ord('a')
if last[c] !=-1:
dp[i+1] = (dp[i+1] - dp[last[c]] + mod) % mod
last[c] = i
return (dp[n] -1) % mod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfndistinct_subseq_ii(s: String) -> i32 {
let n = s.len();
let modn =1_000_000_007;
letmut dp =vec![1; n+1];
letmut last =vec![-1; 26];
let s: Vec<u8>= s.into_bytes();
for i in0..n {
dp[i+1] = (2* dp[i]) % modn;
let c = (s[i] -b'a') asusize;
if last[c] !=-1 {
dp[i+1] = (dp[i+1] - dp[last[c] asusize] + modn) % modn;
}
last[c] = i asi32;
}
((dp[n] -1+ modn) % modn) asi32 }
}