392.判断子序列
这道题目算是 编辑距离问题 的入门题目(毕竟这里只是涉及到减法),慢慢的,后面就要来解决真正的 编辑距离问题了
链接:代码随想录
两种写法,双指针和动态规划。
双指针:
class Solution { //暴力写法都写错了。。。 public: bool isSubsequence(string s, string t) { int n1=s.size(); int n2=t.size(); int i=0,j=0; while(i<n1 && j<n2) { if(s[i]==t[j]) { i++; j++; } else { j++; } } if(i==n1) { return true; } return false; } };
动态规划,自己写的:
class Solution {
/*动态规划自己试着写
子序列那道题是二维动态规划
X a h b g d c
X t t t t t t t
a f t t t t t t
b f f f t t t t
c f
根据填表的规律,dp[i][j]代表s[0...i-1]、t[0...j-1]是否匹配。
如果dp[i][j-1]==true,则dp[i][j]==true;
如果dp[i-1][j-1]==true && s[i-1]==t[j-1],则dp[i][j]==true
*/
public:
bool isSubsequence(string s, string t) {
int n1=s.size();
int n2=t.size();
vector<vector<bool>>dp(n1+1,vector<bool>(n2+1,false));
for(int j=0;j<n2+1;j++)
{
dp[0][j]=true;
}
for(int i=1;i<n1+1;i++)
{
for(int j=1;j<n2+1;j++)
{
if(dp[i][j-1]==true)
{
dp[i][j]=true;
}
else if(dp[i-1][j-1]==true && s[i-1]==t[j-1])
{
dp[i][j]=true;
}
}
}
return dp[n1][n2];
}
};
答案的思路和我自己想的思路很像,只是我把定义dp[i][j]代表s[0...i-1]、t[0...j-1]是否匹配。
答案dp[i][j]代表s[0...i-1]、t[0...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 (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.不同的子序列
链接:代码随想录
但相对于刚讲过 392.判断子序列,本题 就有难度了 ,感受一下本题和 392.判断子序列 的区别。
自己没有推理出来。看了答案:
看完答案后,这个比较好写出来
最后一个位置推理为dp[0][0]==1.
第一遍写报错:
class Solution { /* dp[i][j] 代表s[0...i-1] 与t[0..j-1] 时 t 在s中出现的情况 X b a g X 0 0 0 b 1 1 0 0 a 1 1 1 0 g 1 1 1 1 g 1 1 1 2 if(s[i-1]==t[j-1]) { dp[i][j]=dp[i-1][j-1]+dp[i-1][j] 拿之前的bag匹配 拿之前的ba 和现在的g匹配 } else { dp[i][j]=dp[i-1][j] } */ public: int numDistinct(string s, string t) { int n=s.size(); int m=t.size(); vector<vector<int>>dp(n+1,vector<int>(m+1,0)); for(int i=0;i<n+1;i++) { dp[i][0]=1; } for(int i=1;i<n+1;i++) { for(int j=1;j<m+1;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[n][m]; } };
检查发现:
代码随想录在定义dp数组时用的
<uint64_t>