392.判断子序列

63 阅读1分钟

题目:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

算法:
方法一:双指针

func isSubsequence(s string, t string) bool {
	i, j := 0, 0
	for i < len(s) && j < len(t) {
		if s[i] == t[j] {
			i ++
		}
		j ++
	}
	return i == len(s)
}

方法二:大数据量S优化,动态规划

func isSubsequence(s string, t string) bool {
	lengthT :=  len(t)
	// dp[i][j] 保存字符j在index i及i之后第一次出现的位置
	// dp[i][j] = lengthT 意味着字符串在index i及i之后没有出现过
	dp := make([][26]int, lengthT + 1)
	for i := range dp[lengthT] {
		dp[lengthT][i] = lengthT
	}

	for i := len(t) - 1; i >= 0; i -- {
		for j := 0; j < 26; j ++  {
			if t[i] == byte('a' + j) {
				dp[i][j] = i
			} else {
				dp[i][j] = dp[i + 1][j]
			}
		}
	}
	pos := 0
	i := 0 
	for i < len(s) {
		if dp[pos][int(s[i] - 'a')] == lengthT {
			return false
		}
		pos = dp[pos][int(s[i] - 'a')] + 1
		i ++
	}
	return i == len(s)
}