本题首先想到的写法是用双指针来做,两个指针分别指向两个字符串,然后进行判断
class Solution {
public:
bool isSubsequence(string s, string t) {
int len = 0;
for(size_t i = 0; i < t.size(); i++){
if(t[i] == s[len]){
len++;
}
if(len >= s.size()){
return true;
}
}
if(len >= s.size()){
return true;
}
return false;
}
};
代码随想录 将这道题作为 编辑距离的入门题目 ,本题的动态规划解法是对后面要讲解的编辑距离铺垫,所以学习了他使用动态规划的解法。
- dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。
- if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1(如果不理解,在回看一下dp[i][j]的定义)
- if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];
- 初始化,dp[0][0]和dp[i][0]需要初始化为0;
- 递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],那么遍历顺序也应该是从上到下,从左到右
class Solution {
public:
bool isSubsequence(string s, string t) {
vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
for(size_t i = 1; i <= s.size(); i++){
for(size_t j = 1; j <= t.size(); j++){
if(s[i - 1] == t[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
} else{
dp[i][j] = dp[i][j - 1];
}
}
}
if(dp[s.size()][t.size()] == s.size()){
return true;
}
return false;
}
};