[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实现

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)

代码

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

相关题目

392. Is Subsequence
524. Longest Word in Dictionary through Deleting
720. Longest Word in Dictionary
posted @ 2020-06-10 05:09  CNoodle  阅读(301)  评论(0编辑  收藏  举报