困难-940. 不同的子序列 II

这种类型的题完全没做过,下次做就有个思路了

M(i)表示是以s[i]结尾的子字符数量,F(i)表示到i位置总的子字符数量,N(s[i])记录上一个以s[i]结尾的子字符数量

M(i)=F(i-1)+1

F(i)=F(i-1) + M(i) - N(s[i])

N(s[i])=M(i)

给定一个字符串 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/**
 * @param {string} s
 * @return {number}
 */
var distinctSubseqII = function(s) {
//s=aaac
//f(i)=f(i-1)*2+1-preNum
//preNum=f(preI)
//i=0,存在字符1个 a 1
//i=1,存在字符2个 aa a 2=3-1
//i=2,存在字符3个 a aa aaa 3=2+2+1-2
//i=3,存在字符7个 a aa aaa 7=3+3+1-0
//所以总共3个
    const MOD = 1000000007;
    let n = s.length, total = 0;
    const map={};//上个同类字符的子字符串数量
    for (let i = 0; i < n; ++i) {
        const preNum = map[s[i]]||0;//上个同类字符的子字符串数量
        map[s[i]] = total + 1;
        total = (total + total+1 - preNum + MOD)%MOD;
        
    }
    return total;
};

 

posted @ 2022-10-14 21:21  无工时代  阅读(19)  评论(0编辑  收藏  举报