329 判断子序列
2025年5月26日大约 2 分钟
🚀 相关链接
📜 描述
给定字符串 s
和 t
,判断 s
是否为 t
的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S
,称作 S1, S2, .., Sk
其中 k >= 10亿
,你需要依次检查它们是否为 T
的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
💡 示例
- 输入:
s = "abc", t = "ahbgdc"
- 输出:
true
- 解释:
"abc"
是"ahbgdc"
的子序列。
示例 2
- 输入:
s = "axc", t = "ahbgdc"
- 输出:
false
- 解释:
"axc"
不是"ahbgdc"
的子序列。
📝 提示
0 <= s.length <= 100
0 <= t.length <= 10^4
- 两个字符串都只由小写字符组成。
💭 思路
双指针:
- 使用两个指针分别遍历
s
和t
,如果s
的当前字符与t
的当前字符匹配,则移动s
的指针;否则只移动t
的指针。 - 如果遍历完
s
,则s
是t
的子序列。
- 使用两个指针分别遍历
动态规划(适用于进阶问题):
- 预处理
t
,构建一个二维数组dp
,其中dp[i][j]
表示在t
的第i
个位置之后,字符j
出现的位置。 - 使用该数组快速判断
s
是否为t
的子序列。
- 预处理
💻 代码实现
public boolean isSubsequence(String s, String t) {
int[][] arr = new int[t.length() + 1][26];
for (int i = 0; i < 26; i++) {
arr[t.length()][i] = -1;
}
for (int i = t.length() - 1; i >= 0; i--) {
int charIndex = t.charAt(i) - 97;
arr[i][charIndex] = i;
for (int j = 0; j < 26; j++) {
if (charIndex == j) {
arr[i][j] = i;
} else {
arr[i][j] = arr[i + 1][j];
}
}
}
int currentPos = 0;
for (int i = 0; i < s.length(); i++) {
int charIndex = s.charAt(i) - 97;
int nextPos = arr[currentPos][charIndex];
if (nextPos == -1) {
return false;
} else {
currentPos = nextPos + 1;
}
}
return true;
}