leetcode 940. 不同的子序列 II (动态规划 ,字符串, hash,好题)

题目链接

https://leetcode-cn.com/problems/distinct-subsequences-ii/

题意:

给定一个字符串,判断里面不相同的子串的总个数

思路:

非常巧妙的一个题:
以"abc"为例:不同的子序列有:{a,b,c,ab,ac,bc,abc}
朴素解法:O(2^N)
优化解法:动态规划+字符串hash O(26*N)
设dp[i]表示以'a'+i结尾的字符所含有的不同的子序列的个数
那么根据s[i-1]的情况,最多也就26种可能的情况,即dp[i]<--dp[0]+dp[1]+...+dp[25]+1; //最后加1表示前面的所有可能值都为空的字符串
极大的优化了时间复杂度

class Solution {
public:
//朴素解法时间复杂度 O(N^2)<==假算法,不连续,朴素解法应该是O(2^N)
//字符串hash O(26*N)
    const int Mod=1e9+7;
    int distinctSubseqII(string S) {
        int dp[26]={0};//以i+'a'结尾的不同字符串的总数
        int ans=0;
        for(char c:S){
            int tmp=0;
            for(int i=0;i<26;i++){
                tmp=(tmp+dp[i])%Mod;
            }
            dp[c-'a']=(1+tmp)%Mod;//空了一个子序列
        }

        for(int i=0;i<26;i++){
            ans=(ans+dp[i])%Mod;
        }

        return ans;
    }
};

参考思路:
https://leetcode-cn.com/problems/distinct-subsequences-ii/solution/dong-tai-gui-hua-cong-fen-xi-dao-shi-xian-by-my10y/

posted @ 2020-12-02 11:50  xzhws  阅读(128)  评论(0编辑  收藏  举报