首页 > 其他分享 >940.不同的子序列 II

940.不同的子序列 II

时间:2022-10-14 09:45:47浏览次数:51  
标签:26 结尾 int 940 II 字符串 序列 dp

解题思路:

  • 本题为动态规划思想
  • 基本思想:
    • 以结尾的字母来划分集合,避免重复的子序列。 遍历字符串,更新以当前字符串结尾的子序列数量为:以26个字母为结尾的子序列的数量(就是把当前字符串加到所有子序列的前面) + 1(自身)。 遍历结束以后,以每种字符结束的子序列数量都已经计算好了。
  • 例子:
    • abcac 为例,首先以第一个 a 为结尾的子字符串只有他自己 {a} 故此时的dp['a'-'a']=1;
    • 以此类推,以 b 为结尾的字符串集为 {ab,b} ,故此时的dp['a'-'a']=2;以第一个 c 为结尾的字符集为 {ac,abc,bc,c} ;以第二个 a 为结尾的字符集为 {aa,aba,ba,aca,abca,bca,ca,a} ;

归约:

  • dp 长度为26,每一个位置存储一个以其字母为结尾的子字符串个数

错误代码分析:

class Solution {
public:
    int dp[26];
    int distinctSubseqII(string s) {
        int n=s.length();
        long long mod=pow(10,9)+7;
        for(int i=0;i<n;i++)
        {
            dp[s[i]-'a']+=accumulate(dp,dp+26,1ll)%mod; //错误的位置在这里
        }
        return accumulate(dp,dp+26,0ll)%mod;
    }
};

错误原因是 ‘+’ ,不应该使用 ‘+’ ,由于结尾相同的话,直接更新就行,不用将之前的字符串相加,因为之前找到的会在后面继续找到,被包含了

正确代码:

class Solution {
public:
    int dp[26];
    int distinctSubseqII(string s) {
        int n=s.length();
        long long mod=pow(10,9)+7;
        for(int i=0;i<n;i++)
        {
            dp[s[i]-'a']=accumulate(dp,dp+26,1ll)%mod;
        }
        return accumulate(dp,dp+26,1ll)%mod;
    }
};

复杂度分析:

  • 时间复杂度为O(n);
  • 空间复杂度为O(1);

标签:26,结尾,int,940,II,字符串,序列,dp
From: https://www.cnblogs.com/bzxf/p/16790572.html

相关文章