leetcode
leetcode 351 ~ 400
判断子序列

判断子序列

难度:

标签:

题目描述

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

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

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

致谢:

特别感谢 @pbrother 添加此问题并且创建所有测试用例。

 

示例 1:

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

示例 2:

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

 

提示:

  • 0 <= s.length <= 100
  • 0 <= t.length <= 10^4
  • 两个字符串都只由小写字符组成。

代码结果

运行时间: 15 ms, 内存: 16.0 MB


/*
 * 思路:
 * 使用 Java Stream API 简化实现。
 * 通过对 t 进行过滤,保留那些与 s 中对应字符匹配的字符。
 * 最终检查保留下来的字符是否能组成 s。
 */
import java.util.stream.IntStream;
 
public class Solution {
    public boolean isSubsequence(String s, String t) {
        int[] index = {0};
        return t.chars().filter(c -> index[0] < s.length() && c == s.charAt(index[0])).count() == s.length();
    }
}

解释

方法:

该题解采用了双指针的思路。用两个指针i和j分别指向字符串s和t的开头。遍历字符串t,如果当前字符t[j]等于s[i],则i向右移动。最后判断i是否等于s的长度,如果等于则说明s是t的子序列,否则不是。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在进阶问题中,当有大量的S输入时,需要考虑修改代码?当前的双指针逻辑是否适用于处理大量数据?
当面对大量的S输入时,单个查询的效率变得尤为重要。当前的双指针逻辑对每个查询都需要遍历整个字符串T,时间复杂度为O(n),其中n是T的长度。如果S非常多,这种方法会导致总的时间复杂度非常高。因此,可以考虑预处理T,例如使用哈希表或索引数组记录字符在T中的位置,以实现更快的查询,从而优化对大量S输入的处理。
🦆
你能详细解释为什么在判断s是否为空字符串时,可以直接返回True吗?这里是否考虑了所有可能的场景?
在定义上,空字符串是任何字符串的子序列,因为没有字符需要匹配。因此,不管T是什么,空字符串s总是T的子序列。这里考虑了所有可能的场景,只要s是空的,无论t的内容如何,都应该返回True。
🦆
在算法中,如果s的长度大于t的长度,是否有必要开始遍历t字符串?
如果s的长度大于t的长度,理论上s不可能是t的子序列,因为没有足够的空间在t中按序容纳所有s的字符。因此,可以在开始遍历之前添加一个判断:如果s的长度大于t的长度,直接返回False,这样可以提高算法的效率,避免不必要的遍历。
🦆
如果t中的字符顺序与s中的字符顺序不一致,但所有字符都存在,此算法是否仍然返回false?
是的,该算法会返回false。因为算法不仅检查t中是否存在s的所有字符,还检查这些字符是否以相同的顺序出现。如果顺序不同,即使t包含s的所有字符,算法也不会认为s是t的子序列。

相关问题

匹配子序列的单词数

给定字符串 s 和字符串数组 words, 返回  words[i] 中是s的子序列的单词个数 。

字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。

  • 例如, “ace”“abcde” 的子序列。

 

示例 1:

输入: s = "abcde", words = ["a","bb","acd","ace"]
输出: 3
解释: 有三个是 s 的子序列的单词: "a", "acd", "ace"。

Example 2:

输入: s = "dsahjpjauf", words = ["ahjpjau","ja","ahbwzgqnuk","tnmlanowax"]
输出: 2

 

提示:

  • 1 <= s.length <= 5 * 104
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 50
  • words[i]s 都只由小写字母组成。
​​​​

形成字符串的最短路径

形成字符串的最短路径