58 lines
2.3 KiB
Java
Raw Normal View History

2025-04-22 16:03:25 +08:00
package dynamic_programming;
/**
* 题目 392. 判断子序列 (isSubsequence)
* 描述给定字符串 s t 判断 s 是否为 t 的子序列
* 字符串的一个子序列是原始字符串删除一些也可以不删除字符而不改变剩余字符相对位置形成的新字符串例如"ace""abcde"的一个子序列"aec"不是
*
* 进阶
* 如果有大量输入的 S称作 S1, S2, ... , Sk 其中 k >= 10亿你需要依次检查它们是否为 T 的子序列在这种情况下你会怎样改变代码
示例 1
输入s = "abc", t = "ahbgdc"
输出true
* 链接https://leetcode.cn/problems/is-subsequence/
*/
//不会
public class IsSubsequence {
//动态规划转为求最长公共子序列是否为s的长度
public boolean isSubsequence(String s, String t) {
int length1 = s.length(); int length2 = t.length();
int[][] dp = new int[length1+1][length2+1];
for(int i = 1; i <= length1; i++){
for(int j = 1; j <= length2; j++){
if(s.charAt(i-1) == t.charAt(j-1)){
dp[i][j] = dp[i-1][j-1] + 1;
}else{
dp[i][j] = dp[i][j-1]; //s长度肯定小于等于t 要删也删t
}
}
}
return dp[length1][length2] == length1;
}
//双指针
/**
* 我们用两个指针 i 遍历字符串 sj 遍历字符串 t初始均指向各自字符串的开头
*
* 如果 s.charAt(i) == t.charAt(j)说明匹配上了两个指针都往后走i++, j++
* 否则就只能在 t 跳过这个字符j++
* i 走到 s.length() 说明 s 中的所有字符都在 t 中按顺序找到了返回 true否则 j 扫完 t 还没把 s 的所有字符匹配完就返回 false
*/
public boolean isSubsequence2(String s, String t) {
int i = 0, j = 0;
int n = s.length(), m = t.length();
// 当 i < n 且 j < m 时循环
while (i < n && j < m) {
if (s.charAt(i) == t.charAt(j)) {
// 匹配时,两指针都前进一步
i++;
}
// 不匹配时,只在 t 上跳过
j++;
}
// 如果 i 已经走完 s说明全部匹配
return i == n;
}
}