392.判断子序列

392.判断子序列

题目

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

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

致谢:

特别感谢 @pbrother 添加此问题并且创建所有测试用例。

示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false

提示:

0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/is-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解1-指针

定义一个指向s的指针sp,遍历t字符串,如果s.charAt(sp) == ts.charAt(i),说明当前元素相等,sp++,如果最后sp==s.length()说明s是t的子序列

class Solution {
    public boolean isSubsequence(String s, String t) {
        int sLen = s.length();
        int tLen = t.length();
        if(sLen==0)return true;
        if(sLen>tLen)return false;
        int sp = 0;
        for(int i=0;i<tLen;i++){
            if(s.charAt(sp) == t.charAt(i)){
                sp++;
                if(sp==sLen)return true;
            }
        }
        return false;
    }
}

这里还可以优化为双指针

题解2-动态规划

要学会已知推未知,把学过的东西用起来
如果s是t的子序列,那么s和t的最长公共子序列就是s的长度。

dp[i][j]表示以i-1结尾的字符串与j-1结尾的字符串的最长公共子序列的长度为dp[i][j]

dp[i][j]可以由两个方案推出
如果text1.charAt(i-1) == text2.charAt(j-1),则dp[i][j] = dp[i-1][j-1] + 1
如果text1.charAt(i-1) ≠ text2.charAt(j-1),两个字符串的最后一位不相等,那么字符串text1的[0,i-1]区间和字符串text2的[0,j-1]区间的最长公共子序列长度无法延长,因此dp[i][j]就会继承dp[i-1][j]与dp[i][j-1]中的较大值,dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j])
这里思考还是得围绕递推式主旨如何到这一步?选择哪种走法?
因为有两种路径可以到这一步,一个是text1的[0,i-2]text2的[0,j-1],i在走一步;一个是text1的[0,i-1]text2的[0,j-2],j在走一步

class Solution {
    public boolean isSubsequence(String s, String t) {
        int len1=s.length();
        int len2=t.length();
        int dp[][] = new int[len1+1][len2+1];
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(text1.charAt(i-1) == text2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1] + 1;
                else dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]);
				if(dp[i][j]==len1) return true;
            }
        }
        return false;
    }
}

空间优化
发现dp[i][j]只与三个位置有关dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]

image

class Solution {
    public boolean isSubsequence(String s, String t) {
        int sLen = s.length();
        int tLen = t.length();
        if(sLen==0)return true;
        if(sLen>tLen)return false;
  
         int dp[] = new int[tLen+1];
         int last = 0;
        int tmp = 0;
          for(int i=1;i<=sLen;i++){
              last =dp[0];
            for(int j=1;j<=tLen;j++){
                tmp=dp[j];
                if(s.charAt(i-1) == t.charAt(j-1)){
                    dp[j] = last + 1;
                }
                else dp[j]=Math.max(dp[j-1],dp[j]);
                last =tmp;
				if(dp[j]==sLen) return true;
            }
        }

        return false;
    }
}

posted @ 2021-11-11 21:08  rananie  阅读(52)  评论(0编辑  收藏  举报