leetcode 392
判断子序列
题目描述:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
示例1:
s ="abc", t = "ahbgdc"
返回true
示例2:
s = "axc", t = "ahbgdc"
返回false
解法:动态规划 | 贪心
思路:这道题挺简单,我们只要对两个字符串遍历就可以了,只要s后面的字符都能跟t里边匹配且在匹配的位置在前面所以匹配位置的后面,动态规划的思想体现在一个子序列可以是多个子序列的合成,但必须是往后合成
完整代码:
bool isSubsequence(char * s, char * t){
int slength = strlen(s);
int tlength = strlen(t);
int i, j;
int flag;
int position=-1;
for(i=0; i<slength; i++)
{
flag=0;
for(j=i; j<tlength; j++)
if(s[i]==t[j] && j>position)
{
position = j;
flag=1;
break;
}
if(!flag)
break;
}
if(i==slength)
return true;
else
return false;
}

进阶
当我们有多个子序列进行匹配且t的长度大于10亿时,使用前面的方法效率就特别低了,因此我们需要另外的方法
思路:一个子序列在匹配时,当我们匹配第二个字符时,是不是可以在第一个位置那里查看后边是不是有我们要匹配的字符,因此我们用一个二维数组dp[strlen(t)][26]数组,该数组保存着它后边其他26个字符的位置,如果没有,就是-1
完整代码:
bool isSubsequence(char * s, char * t){
int sl = strlen(s);
int tl = strlen(t);
if(tl==0&&sl!=0)
return false;
else if(tl==0&&sl==0)
return true;
else if(tl!=0&&sl==0)
return true;
/*上面这三行主要是为了应对""这种字符串*/
int dp[tl][26];
for(char c='a'; c<='z'; c++)
{
int nextpos = -1;
for(int i=tl-1; i>=0; i--)
{
dp[i][c-'a']=nextpos;
if(t[i]==c)
nextpos=i;
//如果当前位置的字符等于c,那前面一个字符中的下一个c就是当前位置
}
}
int index=0;
for(int i=(s[0]==t[0]?1:0); i<sl; i++)
{
index = dp[index][s[i]-'a'];
if(index==-1)
return false;
}
return true;
}

心得体会
第一种解法还是挺简单的,毕竟该题的难度是简单,但是进阶的解法确实提供了一个很好的思路,像是建了一张索引表,匹配的时候也不用一个一个的去扫,还能自动的往后推,确实是很好的思路
题目以及解法来源于
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/is-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
博客主要介绍了如何使用动态规划和贪心策略解决LeetCode 392题,即判断一个字符串是否是另一个字符串的子序列。解释了基本解法和当目标字符串非常长时的优化策略,包括建立字符位置索引的方法,以提高匹配效率。
1191

被折叠的 条评论
为什么被折叠?



