给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
题解
本题与Leetcode52最长回文子串的区别在于如果s[i]!=s[j] dp[i][j]=dp[i][j-1]
为什么不可以从dp[i-1][j]转移过来?因为判断s是否为t的子序列,所以可以删除t中的字符(j左移),而不能删除s中的字符(i左移)
class Solution {
//1.确定dp数组含义:dp[i][j],数组s[0:i-1]和数组t[0:j-1]中包含相同字符的个数
//2.确定转移方程:dp[i][j]:如果s[i]==s[j] dp[i][j]=dp[i-1][j-1]+1
//否则 dp[i][j]=dp[i][j-1] (为什么不可以从dp[i-1][j]转移过来?因为判断s是否为t的子序列,所以可以删除t中的字符(t左移),而不能删除s中的字符)
//3.初始化:dp[0][0]=0
//4.遍历顺序:从上到下哦,从左到右
//5.返回值 return dp[i][j]==s.length
public boolean isSubsequence(String s, String t) {
//为什么dp多留一位?为了方便计算dp[i][j]=dp[i-1][j-1]+1以及处理空字符串,注意dp的取值范围也变了
int[][] dp = new int[s.length()+1][t.length()+1];
//注意取值范围
for(int i=1;i<=s.length();i++){
for(int j=1;j<=t.length();j++){
if(s.charAt(i-1)==t.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=dp[i][j-1];
}
}
}
return (dp[s.length()][t.length()]==s.length());
}
}