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; } }