[LeetCode] 392. Is Subsequence

Given two strings s and t, return true if s is a subsequence of t, or false otherwise.

A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., “ace” is a subsequence of “abcde” while “aec” is not).

Example 1:
Input: s = “abc”, t = “ahbgdc”
Output: true

Example 2:
Input: s = “axc”, t = “ahbgdc”
Output: false

Constraints:
0 <= s.length <= 100
0 <= t.length <= 104
s and t consist only of lowercase English letters.
Follow up: Suppose there are lots of incoming s, say s1, s2, …, sk where k >= 109, and you want to check one by one to see if t has its subsequence. In this scenario, how would you change your code?

判断子序列。

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,”ace”是”abcde”的一个子序列,而”aec”不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/is-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路一,双指针

双指针,一个扫描 s,一个扫描 t。如果碰到同样的字母则两个指针都++,否则只移动 t 的指针。t 扫描完毕之后如果 s 没有到末尾则 return false。

复杂度

时间O(t.length())
空间O(1)

代码

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public boolean isSubsequence(String s, String t) {
int i = 0;
int j = 0;
while (i < s.length() && j < t.length()) {
if (s.charAt(i) == t.charAt(j)) {
i++;
}
j++;
}
return i == s.length();
}
}

思路二,动态规划

设 dp[i][j] 为 s 以 i 结尾的子串是否是 t 以 j 结尾的子串的 subsequence。首先 corner case 是当 s 为空的时候,dp[0][j] = true。其次开始扫描,如果匹配(s[i] == t[j]),则 DP 值跟之前一位的 DP 值相同(dp[i][j] == dp[i - 1][j - 1]);如果不匹配,则 dp[i][j] = dp[i][j - 1]。

复杂度

时间O(mn)
空间O(mn)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public boolean isSubsequence(String s, String t) {
int sLen = s.length();
int tLen = t.length();
if (sLen > tLen) {
return false;
}
if (sLen == 0) {
return true;
}
boolean[][] dp = new boolean[sLen + 1][tLen + 1];
// 初始化
for (int j = 0; j < tLen; j++) {
dp[0][j] = true;
}
// dp
for (int i = 1; i <= sLen; i++) {
for (int j = 1; j <= tLen; j++) {
if (s.charAt(i - 1) == t.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = dp[i][j - 1];
}
}
}
return dp[sLen][tLen];
}
}

相关题目

1
2
3
392. Is Subsequence
524. Longest Word in Dictionary through Deleting
720. Longest Word in Dictionary

[LeetCode] 392. Is Subsequence
https://shurui91.github.io/posts/2699056563.html
Author
Aaron Liu
Posted on
June 10, 2020
Licensed under