算法刷题记录 Day47
Date: 2024.04.15
lc 115. 不同的子序列
class Solution {
private:const int MOD = 1e9 + 7;
public:int numDistinct(string s, string t) {// t为模板串,s为原串;int m = t.size();int n = s.size();if(m > n) return 0;// dp[i][j] 表示t[0,i]在s[0,j]的子序列中出现的次数。// dp[i][j] = dp[i][j-1] + dp[i-1][j-1] if t[i] == s[j]vector<vector<int>> dp(m, vector<int>(n, 0));// 根据递推公式,需要初始化第0行和第0列;// 第0列if(s[0] == t[0])dp[0][0] = 1;// 第0行int count = 0;for(int j=0; j<n; j++){if(s[j] == t[0])count++;dp[0][j] = count;}for(int i=1; i<m; i++){for(int j=i; j<n; j++){ // 必须大于等于t的长度才有可能不为0;dp[i][j] = dp[i][j-1];if(t[i] == s[j])dp[i][j] += dp[i-1][j-1];dp[i][j] = dp[i][j] % MOD;}}return dp[m-1][n-1];}
};
lc 392. 判断子序列
// dp
class Solution {
public:bool isSubsequence(string s, string t) {if(s == "") return true;if(s.size() > t.size()) return false;// dp// dp[i][j]表示s以i为结尾和t以j结尾时的子序列长度。// dp[i][j] = dp[i-1][j-1] + 1 if(s[i] == t[j]) else +0;int m = s.size();int n = t.size();vector<vector<int>> dp(m, vector<int>(n, 0));// 根据递推公式,需要初始化第一行和第一列。for(int i=0; i<m; i++){if(s[i] == t[0])dp[i][0] = 1;else{if(i != 0)dp[i][0] = dp[i-1][0];}}for(int j=0; j<n; j++){if(s[0] == t[j])dp[0][j] = 1;else{if(j != 0)dp[0][j] = dp[0][j-1];}}for(int i=1; i<m; i++){for(int j=1; j<n; j++){if(s[i] == t[j]){dp[i][j] = dp[i-1][j-1] + 1;}else{dp[i][j] = max(dp[i-1][j], dp[i][j-1]);}// cout<<"i, j:"<<i<<","<<j<<" dp[i][j]:"<<dp[i][j]<<endl;if(dp[i][j] == s.size()) // 提前退出return true;}}if(dp[m-1][n-1] == s.size()) return true; // 主要为了处理m或n==1时的情况。else return false;}
};// 双指针
class Solution {
public:bool isSubsequence(string s, string t) {// 判断s是否是t的子序列int p1 = 0; // 指向字符串s;int p2 = 0; // 指向字符串t;while(p1 < s.size() && p2 < t.size()){if(s[p1] == t[p2]){p1++;p2++;}else{p2++;}}if(p1 == s.size())return true;elsereturn false;}
};