#include <iostream>
#include <vector>
using namespace std;
/*
题目描述:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符
而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,
而"aec"不是)。
思考:
暴力解法:双重循环,在t中找s中元素,找到后退出内层循环并记录下该索引,选取下个t中
元素,并在s中记录的索引的下一个位置开始遍历。若某次遍历未找到返回false
动态规划:主要操作是在t中遍历寻找匹配的字符,动态规划可以优化这一过程,即通过1查询
memo数组直接得到s中字符对应在t中的索引。
定义memo[i][j]为在t之中第i个位置之后,字符j的索引
初始状态显然为memo[最后索引下一个位置][每个字符]=最后索引下一个位置,
接着向前递推,更新memo[i][字符]=i||memo[i-1][字符]
*/
//dp解法
class Solution{
public:
bool isSubsequence(string s, string t){
int n = s.length(),m = t.length();
//dp数组dp[i][j]表示字符串t以i位置开始第一次出现字符j的位置
vector<vector<int>> dp(m + 1,vector<int> (26,0));
//初始化边界条件,dp[i][j] = m表示t中不存在字符j
for(int i=0;i<26;i++){
dp[m][i] = m;
}
//从后往前递推初始化dp数组
for(int i = m - 1;i>=0;i--) {
for(int j=0;j<26;j++){
if(t[i] == 'a' + j){
dp[i][j] = i;
}else {
dp[i][j] = dp[i + 1][j];
}
}
}
int add = 0;
for(int i = 0;i<n;i++){
//t中没有s[i] 返回false
if(dp[add][s[i] - 'a'] == m){
return false;
}
//否则直接跳到t中s[i]第一次出现的位置之后一位
add = dp[add][s[i] - 'a'] + 1;
}
return true;
}
};
int main(){
return 0;
}
lc392.判断子序列
最新推荐文章于 2024-01-04 16:27:14 发布