392. 判断子序列

392. 判断子序列

题目链接: 392. 判断子序列(简单)

给定字符串 st ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false

提示:

  • 0 <= s.length <= 100

  • 0 <= t.length <= 10^4

  • 两个字符串都只由小写字符组成。

解题思路

本题最直接的方法就是用“双指针”来解决,时间复杂度为O(N)Nt的长度。

此处我们采用动态规划来解答,其实这道题虽说是判断t字符串是不是s字符串的子序列,但也可以按照1143. 最长公共子序列 的思想来求两个字符串的最长公共子序列,然后判断得到的结果是否等于s的长度。

不过,为了体现“字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串”,也就是考虑“删除”,递推公式可以发生一些变化。

C++

class Solution {
public:
    bool isSubsequence(string s, string t) {
        if (s.size() == 0) return true;
        if (s.size() > t.size()) return false;
        // 1. dp数组的含义
        // dp[i][j] 表示以下标i - 1为结尾的 s,和以下标j - 1为结尾的 t,相同子序列的最大长度
        // 3. 初始化
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1 , 0));
        // 4. 遍历顺序,从上到下,从左到右
        for (int i = 1; i <= s.size(); i++) {
            for (int j = 1; j <= t.size(); j++) {
                // 2. 递推公式
                // 如果s[i - 1] 等于 t[j - 1],也就是找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1
                if (s[i - 1] == t[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    // dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                    // 如果s[i - 1] 不等于 t[j - 1],此时相当于t要删除元素,t如果把当前元素t[j - 1]删除
                    // 那么dp[i][j] 的数值就是 s[i - 1]与 t[j - 2]的比较结果(dp[i][j - 1])
                    dp[i][j] = dp[i][j - 1];
                }
            }
        }
        if (dp[s.size()][t.size()] == s.size()) return true;
        else return false;
    }
};

JavaScript

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isSubsequence = function(s, t) {
    const dp = Array(s.length + 1).fill().map(item => Array(t.length + 1).fill(0));
    for (let i = 1; i <= s.length; i++) {
        for (let j = 1; j <= t.length; j++) {
            if (s[i - 1] === t[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }
    return s.length === dp[s.length][t.length];
};
  • 时间复杂度:O(n × m)

  • 空间复杂度:O(n × m)

posted @ 2022-03-17 11:09  wltree  阅读(84)  评论(0编辑  收藏  举报