代码随想录算法训练营第58天 | 392.判断子序列 115.不同的子序列

判断子序列

这道题可以双指针方法解决。

cpp 复制代码
class Solution {
public:
	bool isSubsequence(string s, string t) {
		int s_index = 0;
		for(int t_index = 0; t_index < t.size(); t_index++) {
			if(s[s_index] == t[t_index]) {
				s_index++;
			}
		}
		return s_index == s.size();
	}
};

用动态规划也是可解的,是简化的编辑距离问题。通过删除 t 中的字符得到 s,求解能否实现。dp[i][j] 表示 i-1 之前的字符串s子串和 j-1 之前的字符串t子串之间的最长公共子序列长度。这道题与上一道最长公共子序列是相同的。

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 {
					// 因为是判断s是不是t的子序列,所以只删除t中的字符就可以,从dp[i][j-1]继承数值
					dp[i][j] = dp[i][j - 1];  
				}
			}
		}
		return dp[s.size()][t.size()] == s.size();  // 最长公共子序列与s一样长,说明s就是t的子序列
	}
};

不同的子序列

这道题也是编辑距离类型的问题。本题中只涉及删除操作,对字符串 s 删除字符得到 t,求解操作方案的数目。

dp[i][j] 表示从字符串 s 下标 i-1 之前子串通过删除字符得到字符串 t 下标 j-1 之前子串的方案数目。

递推公式:针对这类问题我们可以发现,只需要考虑两种情况s[i - 1] == t[j - 1]s[i - 1] != t[j - 1]。对于第一种情况,可以用 s[i - 1] 进行匹配,这部分的方法数目是 dp[i - 1][j - 1],也可以不用 s[i - 1] 进行匹配,这部分的数目继承自 dp[i - 1][j];对于第二种情况,没法匹配上 s[i - 1] 和 t[j - 1],只能继承自 dp[i - 1][j]。

初始化:dp[0][j] 意味着空数组转换成字符串 t,没有方案可以实现,初始化为0。dp[i][0] 意味着字符串 s 转换成空数组,只有一种方案,初始化为1。dp[0][0]表示空数组到空数组,初始化为1。

cpp 复制代码
class Solution {
public:
	int numDistinct(string s, string t) {
		vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
		int max_value = INT_MAX;
		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]) {
					if(dp[i - 1][j] < max_value - dp[i - 1][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()];
	}
};
相关推荐
小黄人软件36 分钟前
PCI认证 密钥注入 ECC算法工具 NID_secp521r1 国密算法 openssl 全套证书生成,从证书提取公私钥数组 x,y等
算法·https·ssl
牛奶咖啡.8541 小时前
树和图论(详细整理,简单易懂!)
数据结构·c++·算法·深度优先·图论
2401_881244402 小时前
416. 分割等和子集
数据结构·算法
butterfly_onfly2 小时前
C# 多线程并发编程基础
数据结构·算法·c#
Gsen28192 小时前
聚类算法 ap 聚类 谱聚类
人工智能·算法·机器学习·数据挖掘·聚类
XYY3694 小时前
搜索与图论 树的广度优先遍历 图中点的层次
算法·图论·宽度优先
python_chai5 小时前
Python核心数据结构详解:元组、集合与字典
java·数据结构·python
爱编程的王小美5 小时前
8876行详解数据结构,从入门到入坟
数据结构
Fantasydg7 小时前
DAY 38 leetcode 15--哈希表.三数之和
算法·leetcode·散列表
编程绿豆侠7 小时前
力扣HOT100之链表:19. 删除链表的倒数第 N 个结点
算法·leetcode·链表