匹配子序列--动态规划

博客主要介绍了如何使用动态规划和贪心策略解决LeetCode 392题,即判断一个字符串是否是另一个字符串的子序列。解释了基本解法和当目标字符串非常长时的优化策略,包括建立字符位置索引的方法,以提高匹配效率。

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值