LeetCode[392. Is Subsequence] 难度[medium]

本文介绍了一种算法,用于检查一个字符串是否为另一个字符串的子序列。提供了两种解决方案:一种是直接遍历,时间复杂度为O(n);另一种是采用动态规划的方法,虽然空间和时间复杂度较高,但在某些场景下可能更为适用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Given a string s and a string t, check if s is subsequence of t.

You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100).

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, “ace” is a subsequence of “abcde” while “aec” is not).
意思就是判断一个字符串是不是另一个字符串的子序列(即不用连续)

算法思路

这题最直接的做法就是直接把字符串t遍历一遍,看字符串s的字符是否按顺序出现,算法时间复杂度是O(n),实现如下

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int n1 = s.size(), n2 = t.size();
        int k = 0;
        for(int i=0; i<n2; ++i){
            if(s[k]==t[i])  k++;
        }
        if(k == n1)   return true;
        else    return false;
    }
};

另外一个做法是使用动态规划思想,用一个二维数组布尔f[i][j]为true表示字符串s的前i个字符是字符串t的前j个字符的子序列,这样我们可以知道f[0][j]为true,f[i][0]为false,f[i][j]为true就两种情况,一是t的前j-1个已经包含了s的前i个,二是t的前j-1个包含了s的前i-1个且s第i个和t第j个相等,即f[i][j] = f[i][j-1] || f[i-1][j-1]&&s[i-1]==t[j-1] 。最后的结果就是f[n][m],n是s的长度,m是t的长度。 我们可以看出来f[i][j]依赖于f[i-1][j]和f[i-1][j-1],所以为了节省空间,i可以只用0/1表示。该算法时间复杂度为O(mXn),具体实现如下

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int n,m,k,i,j;
        n = s.size();
        m = t.size();
        for(i=0; i<=m; ++i)  f[0][i] = true;
        for(k=i=1; i<=n; ++i, k=1-k){
            f[k][0] = false;
            for(j=1;j<=m; ++j)
                f[k][j] = f[k][j-1]||f[1-k][j-1]&&s[i-1]==t[j-1];
        }
        return f[1-k][m];
    }
private:
    bool f[2][600000];
};

显然本题使用最直接的算法能得到更好的效率而且更加简单,所以不要盲目地去使用动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值