首页 > 其他分享 >图解LeetCode——940. 不同的子序列 II(难度:困难)

图解LeetCode——940. 不同的子序列 II(难度:困难)

时间:2023-05-23 11:01:51浏览次数:36  
标签:字符 遍历 940 II sc 总数 字符串 序列 LeetCode


一、题目

给定一个字符串 s,计算 s不同非空子序列 的个数。因为结果可能很大,所以返回答案需要对 10^9 + 7 取余

字符串的 子序列 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。

例如:"ace" 是 "abcde" 的一个子序列,但 "aec" 不是。

二、示例

2.1> 示例 1:

【输入】s = "abc"
【输出】7
【解释】7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。

2.2> 示例 2:

【输入】s = "aba"
【输出】6
【解释】6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。

2.3> 示例 3:

【输入】s = "aaa"
【输出】3
【解释】3 个不同的子序列分别是 "a", "aa" 以及 "aaa"。

提示:

  • 1 <= s.length <= 2000
  • s 仅由小写英文字母组成

三、解题思路

根据题目描述,要找出一个字符串中所有不同的子序列。那么我们就需要找出这种子序列组合的规律。为了排除其他干扰,我们假设字符串中素有的字符都是不重复的。如下图所示,s=“abcd”,那么我们可以看到如下规律:

  • 遍历第1个字符‘a’:子序列总数 = 1(字符‘a’本身)= 1
  • 遍历第2个字符‘b’:子序列总数 =【字符'a'的子序列总数】+ 1(字符‘b’本身)= 1 + 1 = 2
  • 遍历第3个字符‘c’:子序列总数 =【字符'a'的子序列总数】+ 【字符'b'的子序列总数】+ 1(字符‘c’本身)= 1 + 2 + 1 = 4
  • 遍历第4个字符‘d’:子序列总数 =【字符'a'的子序列总数】+【字符'b'的子序列总数】+【字符'c'的子序列总数】+ 1(字符‘d’本身)= 1 + 2 + 4 + 1 = 8
  • 【总结果】 = 1 + 2 + 4 + 8 = 15

图解LeetCode——940. 不同的子序列 II(难度:困难)_bc

但是,题目中并没有限制字符不能重复,所以,我们这时候在考虑如果字符串中出现重复字符,对总结果的影响是怎样的?请见下图,我们以s=“abcb”为例,我们发现,里面有字符‘b’发生了重复,我们发现如下规律:

在第1次遍历到字符‘b’的时候:子序列为“ab”、“b”;
在第2次遍历到字符‘b’的时候:子序列为“ab”、“b”、“abb”、“bb”、“acb”、“abcb”、“bcb”、“cb”;
【结论】我们发现第2次遍历字符'b'的时候,已经包含了第1次遍历字符'b'的子序列了。所以,在统计最终结果的时候,我们需要把“上一次”相同字符子序列总数减去才可以。

图解LeetCode——940. 不同的子序列 II(难度:困难)_子序列_02

基本思路就是这样了,具体代码实现,请参照如下部分。

四、代码实现

class Solution {
    public int distinctSubseqII(String s) {
        int mod = (int)1e9 + 7;
        long result = 0L;
        long[] letter = new long[26]; // 记录26个字符每个字符的子序列总数
        for (char sc : s.toCharArray()) {
            long pre = letter[sc - 'a']; // 获得字符sc前一次统计的子序列数
            letter[sc - 'a'] = (result + 1) % mod; // 计算当前字符sc的子序列数
            result = (result + letter[sc - 'a'] - pre + mod) % mod; // 加mod的目的是为了防止结果溢出为负数
        }
        return (int)result;
    }
}

图解LeetCode——940. 不同的子序列 II(难度:困难)_字符串_03

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

标签:字符,遍历,940,II,sc,总数,字符串,序列,LeetCode
From: https://blog.51cto.com/u_15003301/6330127

相关文章

  • 图解LeetCode——1441. 用栈操作构建数组(难度:中等)
    一、题目给你一个数组target和一个整数n。每次迭代,需要从 list={1,2,3...,n}中依次读取一个数字。请使用下述操作来构建目标数组target:"Push":从list中读取一个新元素,并将其推入数组中。"Pop":删除数组中的最后一个元素。如果目标数组构建完成,就停止读取更多元......
  • 图解LeetCode——886. 可能的二分法(难度:中等)
    一、题目给定一组 n 人(编号为 1,2,...,n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。给定整数n 和数组dislikes ,其中 dislikes[i]=[ai,bi] ,表示不允许将编号为ai 和  bi的人归入同一组。当可以用这种方法将所有人......
  • 图解LeetCode——827. 最大人工岛(难度:困难)
    给你一个大小为nxn二进制矩阵grid。最多只能将一格 0变成 1。返回执行此操作后,grid中最大的岛屿面积是多少?岛屿由一组上、下、左、右四个方向相连的 1形成。二、示例2.1>示例1:【输入】grid=[[1,0],[0,1]]【输出】3【解释】将一格0变成1,最终连通两个小......
  • 图解LeetCode——904. 水果成篮(难度:中等)
    一、题目你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组fruits表示,其中fruits[i]是第i棵树上的水果种类。你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:你只有两个篮子,并且每个篮子只能装单一类型的水果......
  • Yii2-app-advanced的配置文件优先级
    Yii2高级模板中支持多套环境配置,并且有优先级重写覆盖默认有两种dev和prod,在应用目录environments 下Yii2中的config配置文件(main.php和params.php)具有极大的灵活配置,结合配置文件的加载顺序1、使用约定 -应用目录下有config/main.php和params.php是一个全职全集......
  • IIS/如何查看IIS上部署网站的实时连接数
    我们在IIS发布的Web网站,如何查看网站实时的连接数呢?1、首先打开运行框,输入perfmon.msc  2、打开监视工具-->性能监视器  3、点击“+”号,添加计数项WebService/CurrentConnections  4、可以查看到网站的实时连接数(线条颜色、粗细可以修改)  PS:本人IIS网站......
  • #yyds干货盘点# LeetCode程序员面试金典:平衡二叉树
    题目:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例1:输入:root=[3,9,20,null,null,15,7]输出:true示例2:输入:root=[1,2,2,3,3,null,null,4,4]输出:false示例3:输入:root=[]......
  • #yyds干货盘点# LeetCode程序员面试金典:分数到小数
    1.简述:给定两个整数,分别表示分数的分子 numerator和分母denominator,以字符串形式返回小数。如果小数部分为循环小数,则将循环的部分括在括号内。如果存在多个答案,只需返回任意一个。对于所有给定的输入,保证答案字符串的长度小于104。 示例1:输入:numerator=1,denominat......
  • Yii2连接多个数据库
    1、使用高级模板yii2-app-advanced2、设置common\config\main-local.php本地文件'components'=>['db'=>['class'=>'yii\db\Connection','dsn'=>'mysql:host=local......
  • 02、SECS-II 通信协议介绍
    这里我们先学习SECS-II协议,给我的感受是先学完SECS-II协议,再去学习SECS-I和HSMS协议更加容易理解,所以这里我先介绍SECS-II协议。文章的内容基本上来自参考资料和自己看的文档,若有侵权,请联系删除,谢谢。1、SECS-II概述消息协议用于在主机和设备(HostandEquipme......