58 lines
2.3 KiB
Java
58 lines
2.3 KiB
Java
|
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 遍历字符串 s,j 遍历字符串 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;
|
|||
|
}
|
|||
|
}
|