判断子序列

博客介绍了如何判断一个字符串是否为另一个字符串的子序列,提供了双指针法、动态规划法和逐个查找三种解法。重点讨论了动态规划法,通过dp矩阵判断子序列,并解释了递推公式和边界条件。
摘要由CSDN通过智能技术生成

问题描述

给定字符串s和t,判断s是否为t的子序列?

解法1:双指针法

思路很简单,设计两个指针,分别用以遍历母字符串t和子字符串t.每一次遍历到子字符串的某个元素,开始遍历母字符串,直到母字符串也有相同的元素对应,这之后指向两个字符串的指针分别自增1.再进行如上判断.直到对于子串的某个元素母串没有对应的匹配或者子串遍历完毕为止.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原理很简单,在此就不贴代码了(其实我也没写哈哈)

解法2.动态规划法

其实动态规划法特别适合求这种判断子串子序列的问题,之前的博客中曾经具体讨论过求两个字符串的公共子串和公共子序列的长度的问题.这里其实也差不多.我们用dp[i][j]来表示字符串t的前j个字符包含s的前i个字符,如果确实包含,则为true,否则为false.
它的递推公式是这样的:
1.如果s[i] == t[j],那么dp[i][j] = dp[i-1][j-1].也就是说,如果s的第i个元素等于t的第j个元素,那么t的前j个元素是否包含s的前i个元素本质上和t的前j-1个元素是否包含s的前i-1个元素这两个问题是等价的,这个可以参考我之前的一篇博客
一篇文章带你读懂什么是编辑距离

2.如果s[i] != t[j],说明t的第j个元素并不等于s的第i个元素,但是它也不一定就是false.因为当j>k>=i的时候很有可能t的前k个元素就已经实现了包含s的前i个元素了,所以dp[i][j] = dp[i-1][j],也就是判断t的前j个元素是否包含s的前i个元素等价于判断t的前j-1个元素是否包含s的前i个元素.
我们用j指向母串t,用i指向子串i也是有深意的.因为按照我们的习惯,总是逐行填满元素,也就是先遍历母串,固定子串的元素,这就类似于双指针法中固定一个子串元素,寻找母串中是否有元素与之相等.如果母串中的某个元素和子串中的某个元素相等,这只是dp[i][j] = true的必要条件,**因为子序列是有顺序的,这也就表示s中的所有元素在t中保持相同的顺序,**才能说明t中有s这个子序列,如果只找到两个元素相等,还要看这个相等的元素位于s的位置,如果是第一个,那自然是true.但如果不是第一个,那就需要看t中这个元素之前的元素是否包含s中这个元素之前的元素,也就是j指针不断的后退去寻找s中前面的元素的对应.这在动态规划中,就变成了查看它的前一行前一列是否为true.接下来就是确定边界条件了,根据上面的分析,我们得知,**s的第一个元素在t中存在是s中前两个元素是t中的子序列的前提,而s的第二个元素在t中存在也是s中前三个元素是t中的子序列的前提…,**所以我们只要分别写满第一行和第一列这也就是边界条件了.
代码如下:

public class JudgeIfSubString {
   
    public boolean isSubsequence(String s, String t){
   
        if(s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值