首页 > 其他分享 >【Leetcode940】不同的子序列 II

【Leetcode940】不同的子序列 II

时间:2022-10-17 19:56:57浏览次数:49  
标签:aba abc int Leetcode940 II 字符串 序列 dp

1.题目

给定一个字符串 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 仅由小写英文字母组成

2.分析思路

这个方法是一个acmer和我一起慢慢分析得出,大致过程就是动态规划。

设状态dp[i]: 以位置i结尾的子序列个数.如字符串“abc”

dp[0]=1,就一个a;dp[1]=2,以字符b结尾的子序列的数目:b、ab;dp[2]=4;c,ac,bc,abc;

abc的子序列个数为dp[0]+dp[1]+dp[2]=1+2+4=7;


如字符"aba"

dp[0]=1,a;dp[2]=2,b,ab;dp[3]=3,aa,ba,aba;

aba子序列的个数为dp[0]+dp[1]+dp[2]=1+2+3=6;


从上述分析可以得出,当字符串没有重复字符时,dp[i+1]=dp[i]+dp[i-1]+....+dp[0]+1;

最后的子序列的个数:


但是当字符串中有重复子串的时候:

需要减去重复的值,并且更新i位置的dp[i]及之后的dp[i+1].....

如字符"aba"

dp[0]=1,a;

dp[2]=2,b,ab;

dp[3]=3=(4-1),aa,ba,aba,(a);

aba子序列的个数为dp[0]+dp[1]+dp[2]=1+2+3=6;

这我实现的不太好,使用了暴力方法进行遍历dp,更新dp,时间复杂度较高。

3.代码实现

class Solution {
    public int sum=0;
    public int summ(int a[],int num)
    {
        int results=0;
        for(int i=0;i<num;i++)
        {
            //System.out.println("遍历num:"+a[i]);
            results=(int)((results+a[i])%(Math.pow(10,9)+7));
        }
        return results;
    }
    public int distinctSubseqII(String s) {
        int results=0;
        Map<Character,ArrayList<Integer>>map=new HashMap<Character,ArrayList<Integer>>();//数据结构
        int leng=s.length();
        int nums[] =new int[leng];
        nums[0]=1;
        double M=Math.pow(10,9)+7;
        for(int i=0;i<s.length();i++)//获取是否重复的值
        {
            //ArrayList<Integer> list=new ArrayList<Integer>();
            Character c=s.charAt(i);
            boolean b = map.containsKey(c);
            if(b)
            {
                //System.out.println("存在"+b);
               ArrayList<Integer> value = map.get(c);
               value.add(i);
            }
            else
            {
                ArrayList<Integer> value=new ArrayList<Integer>();
                value.add(i);
                map.put(c,value);
            }
        }
        for(int i=1;i<s.length();i++)
        {
            sum=(int)((sum+nums[i-1])%(M));
            nums[i]=(int)((sum+1)%(M));
        }
        sum=(int)((sum+nums[s.length()-1])%(M));
        results=(int)sum;
        int dif[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        if(map.size() !=s.length() && map.size()!=1)
        {
            for(int x=0;x<s.length();x++)
            {
                int t=s.charAt(x)-'a';
                if(dif[t]!=0)
                {
                    nums[x]=(int)((nums[x]-dif[t])%(M));
                    if(nums[x]<0)
                    {
                         nums[x]+=(int)M;
                    }
                    int index=x;
                    sum=(int)((summ(nums,index+1))%(M));
                    while(index<(s.length()-1))//求新的dp
                    {
                        //Character key=s.charAt(index);
                        nums[index+1]=(int)((sum+1)%(M));
                        sum=(int)((sum+nums[index+1])%(M));
                        index++;
                    }
                }
                dif[t]=(int)((dif[t]+nums[x])%(M));
            }
            results=summ(nums,s.length());
        }
        else if(map.size() == 1)
            results=s.length();
        return results;
    }
}

 

标签:aba,abc,int,Leetcode940,II,字符串,序列,dp
From: https://www.cnblogs.com/echoqiqi/p/16800379.html

相关文章

  • linux服务器如何查看硬盘序列号
      命令: hdparm-I 硬盘绝对路径--其中参数可以使用 “I”也可以使用 “i”,只是大写的参数展示的数据更详细;注:这个命令普通用户无法使用,需要使用管理员权限;......
  • 【Python】第3章-6 求整数序列中出现次数最多的数
    本题要求统计一个整型序列中出现次数最多的整数及其出现次数。输入格式:输入在一行中给出序列中整数个数N(0<N≤1000),以及N个整数。数字间以空格分隔。输出格式:在一行中输......
  • 【意外之中新发现——类图,序列图】
    前言:     VS是我们学习C#语言接触的新的工具,现在做vb.net版的机房收费系统,也是基于VS环境的,从开始的控制台应用程序,类,接口,到窗体应用程序,这是在学习的过程中,逐渐积......
  • gson序列化null
    问题:当一个字段为null时,json数据不显示字段名称Mapm=NewHashMap();m.put(“a”,null);输出:newGson().toJson(m);预期结果:{a:null}实际结果:{}解决方式:使用GsonBui......
  • quartus II输入原理图及仿真步骤(转)
    https://www.cnblogs.com/mikewolf2002/p/10237681.html?ivk_sa=1024320uquartusII输入原理图及仿真步骤   在QuartusII中输入原理图以及实现仿真是学习基本数字......
  • ASCII码对应表,回车、换行、空格的ASCII码值
    回车:ASCII码13,“\r”换行:ASCII码10,“\n”空格:ASCII码32Return=CR=13='\x0d'NewLine=LF=10= '\x0a' \r与\n的区别:\r:return到当前行的最......
  • 子序列与子数组(子串)
    子序列与子数组(子串)区别子序列元素在原数组的下标不连续,相对位置不可改变例如[1,2,3,4,5]->[1,3,5]子数组(子串)元素在原数组的下标连续,相对位置不可变例......
  • 源码分析之序列化器的many关键字
    在序列多个数据时,我们需要指定一个关键字many=True这是为什么呢?其实是,当序列化器产生对象时,传入参数many和不传入会生成两个不同的对象!!这是怎么实现的呢??1.类的对象生......
  • leetcode-240. 搜索二维矩阵 II --z字搜索
    240.搜索二维矩阵IIZ字搜索法,持续缩小target可能在的范围,从右上角进入矩阵开始搜索,左下角也是一样的,但是不能从左上角或右下角开始范围:x再大也不能超过矩阵宽度,y......
  • 深度学习与统计力学(III) :神经网络的误差曲面
    谷歌和斯坦福最新合作综述报告,发表在物理学的顶级期刊“凝聚态物理年鉴”(AnnualReviewofCondensedMatterPhysics)。作者YasamanBahri,JonathanKadmon,JeffreyPenni......