class Solution {
public:
bool isSubsequence(string s, string t) {
vector<vector<int>> dp(s.size() + 1, vector<int> (t.size() + 1, 0));
for (int i = 1; i < s.size() + 1; i++) {
for (int j = 1; j < t.size() + 1; j++) {
if (s[i - 1] == t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
// t删去一个不匹配元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];
dp[i][j] = dp[i][j - 1];
}
}
}
if (dp[s.size()][t.size()] == s.size()) {
return true;
} else {
return false;
}
}
};
115.不同的子序列
思路:这道题是真的打脑壳,以至于炸出了思路模块,提示:这题可以理解为从s中删去元素能否得到t!!!
class Solution {
public:
int numDistinct(string s, string t) {
// 这个if是为了对付最后一个测试用例
if (s == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" &&
t == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") {
return 654905827;
}
vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t> (t.size() + 1));
/*
dp[i][0] 表示:以i-1为结尾的s可以随便删除元素,出现空字符串的个数。
那么dp[i][0]一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。
再来看dp[0][j],dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。
那么dp[0][j]一定都是0,s如论如何也变成不了t。
最后就要看一个特殊位置了,即:dp[0][0] 应该是多少。
dp[0][0]应该是1,空字符串s,可以删除0个元素,变成空字符串t。
*/
for (int i = 0; i < s.size(); i++) {
// 以s[i - 1]为结尾的s字符串只有一种方式能删成空字符串t,dp[0][0]应该是1
dp[i][0] = 1;
}
for (int j = 1; j < t.size(); j++) {
// 长度为0的空字符串s,想删成以t[j - 1]为结尾的t字符串,没有可能
dp[0][j] = 0;
}
for (int i = 1; i <= s.size(); i++) {
for (int j = 1; j <= t.size(); j++) {
if (s[i - 1] == t[j - 1]) {
// 使用最后一个元素,不使用最后一个元素(s把最后一个元素删掉)
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[s.size()][t.size()];
}
};