题目链接
英文链接:https://leetcode.com/problems/is-subsequence/
中文链接:https://leetcode-cn.com/problems/is-subsequence/
题目详述
给定字符串 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,称作S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
题目详解
每次记录待查询的起点,对每个 s 中的字符直接在 t 中进行查询,若找不到对应字符,说明 s 不可能为 t 的子序列。
1 | public class LeetCode_00392 { |
后续挑战 :如果有大量输入的 S,称作S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。设 S 的长度为 M,T 的长度为 N,则上面的做法时间复杂度为 O(kMN)。由于 T 对于每个 S 而言是相同的,可以对 T 进行处理,进行优化。
- 按升序记录每个字符在 T 中出现的下标(对于多个 S 而言,只需要执行一次)。
- 对于每一个 S,进行遍历并在对应字符的下标集合中进行二分查找,看是否能找到满足条件的下标(由 index 进行维护)。
- 只要上述过程有不满足条件的地方,说明 S 不可能为 T 的子序列,可以直接返回 false。
可以认为二分查找的过程平均时间复杂度为 O(logX),最坏情况下为 O(N),并且 O(logX) 远小于 O(N)。对于每一个 S ,时间复杂度为 O(MlogX)。对于 k 个 S,时间复杂度为 O(kMlogX)。
1 | public class LeetCode_00392 { |