题目描述
原题链接:392. 判断子序列
解题思路
(1)双指针法
i
指向字符串t
,遍历整个字符串t
。j
指向字符串s
,在遍历字符串t
的过程中,每遇到一个i
指向元素和j
指向元素相等时,则让j
移动到下一个位置。由此方式,遍历完整个字符串t
,然后判定是否j
已遍历完整个字符串s
。
class Solution {
public:
bool isSubsequence(string s, string t) {
int n1 = s.size(), n2 = t.size();
if(n1 > n2) return false;
int j = 0;
for(int i = 0; j < n1 && i < n2; i++) {
if(s[j] == t[i]) j++;
}
return j == n1 ? true : false;
}
};
(2)动态规划
整体思路与 718. 最长重复子数组(动态规划) 相同,在遇到s[i - 1] == t[j - 1]
的时候,从上一个状态转移过来,dp[i - 1][j - 1] + 1
。在遇到s[i - 1] != t[j - 1]
的时候,因为要求字符串s为t的子串,因此固定s末尾指向位置不动,让指向t的指针向前面移动一个,由此位置转移状态,即dp[i][j] = dp[i][j - 1]
。
class Solution {
public:
bool isSubsequence(string s, string t) {
int n1 = s.size(), n2 = t.size();
if(n1 > n2) return false;
vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1));
for(int i = 1; i <= n1; i++) {
for(int j = 1; j <= n2; 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];
}
}
}
return dp[n1][n2] == n1 ? true : false;
}
};