940. 不同的子序列 II

动态规划:求子序列问题经常可以用动态规划,用f[i]表示以字符串s[i]字符为最后一个字符时一共有多少个不重复非空子序列,i为最后一个字符,那么只需要累加倒数第二个字符的位置就可以求出f[i],但这样算出来的结果是有重复值的,比如位置不同的相同字符算出来的值位置靠后算出来的子序列是包含位置靠前的子序列,那么在之后算某个字符的子序列数量时累加这两个值就会把重复的值累加,由此可以看出在求某个以该位置结尾的子序列时,如果倒数第二个字符相同时,我们只需要加位置靠后的数量即可,答案就是所有字母所在的最后一个位置的f[i]之和

code :


class Solution {
    private final int MOD = 1000000007 ;
    private int[] dp = new int[2010];
    private int [] site = new int[30];
    public int distinctSubseqII(String s) {
        Arrays.fill(site,-1);
        Arrays.fill(dp,0);
        for(int i = 0;i<s.length();i++){
            dp[i] = 1;
            for(int j = 0;j<26;j++){
                if(site[j] == -1)
                    continue;
                dp[i] = (dp[i]+dp[site[j]])%MOD;
            }
            site[s.charAt(i)-'a'] = i;
           
        }
        int ans = 0;
        for(int j= 0;j<26;j++){
            if(site[j] == -1)
                continue;
            ans = (ans+dp[site[j]])%MOD;
        }
        return ans;
    }
}
posted @ 2022-10-14 17:54  loliconsk  阅读(50)  评论(0)    收藏  举报