392.判断子序列
dpij 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dpij。
- if (si - 1 == tj - 1)
- t中找到了一个字符在s中也出现了
- if (si - 1 != tj - 1)
- 相当于t要删除元素,继续匹配
if (si - 1 == tj - 1),那么dpij = dpi - 1j - 1 + 1;,因为找到了一个相同的字符,相同子序列长度自然要在dpi-1j-1的基础上加1(如果不理解,在回看一下dpij的定义)
if (si - 1 != tj - 1),此时相当于t要删除元素,t如果把当前元素tj - 1删除,那么dpij 的数值就是 看si - 1与 tj - 2的比较结果了,即:dpij = dpij - 1;
cpp
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(); i ++)
{
for(int 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;
}
};
115.不同的子序列
dpij:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dpij。
- si - 1 与 tj - 1相等
- si - 1 与 tj - 1 不相等
当si - 1 与 tj - 1相等时,dpij可以有两部分组成。
一部分是用si - 1来匹配,那么个数为dpi - 1j - 1。即不需要考虑当前s子串和t子串的最后一位字母,所以只需要 dpi-1j-1。
一部分是不用si - 1来匹配,个数为dpi - 1j。
cpp
class Solution {
public:
int numDistinct(string s, string t) {
vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1));
for(int i = 0; i < s.size(); i++)
{
dp[i][0] = 1;
}
for(int j = 1; j < t.size(); j++)
{
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]) 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()];
}
};