题目
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
示例 1:
s = “abc”, t = “ahbgdc”
返回 true.
示例 2:
s = “axc”, t = “ahbgdc”
返回 false.
解题思路
dp版:
用dp[i][j]
表示s[:i]
是否为t[:j]
的子序列,则转移方程:
dp[i][j]={dp[i−1][j−1], if s[i]==t[j]dp[i][j−1], else
dp[i][j] =
\begin{cases}
dp[i - 1][j - 1], \; &if \; s[i] == t[j] \\
dp[i][j - 1], \; &else
\end{cases}
dp[i][j]={dp[i−1][j−1],dp[i][j−1],ifs[i]==t[j]else
初始状态:dp[0][0] = True, dp[0][j] = True, dp[i][0] = False
时间复杂度是o(m∗n)o(m * n)o(m∗n),m和n分别是两个字符串的长度
双指针:
两个指针分别指向s, t
,如果s[i1] == t[i2]
,则i1 += 1, i2 += 1
,否则i2 += 1
,如果最后i1
走完了,则说明是子序列
时间复杂度是o(m+n)o(m + n)o(m+n)
代码
dp版:
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
dp = [[False] * (len(t) + 1) for _ in range(len(s) + 1)]
# init
for col in range(len(t) + 1):
dp[0][col] = True
for row in range(1, len(s) + 1):
for col in range(1, len(t) + 1):
if s[row - 1] == t[col - 1]:
dp[row][col] = dp[row - 1][col - 1]
else:
dp[row][col] = dp[row][col - 1]
return dp[-1][-1]
双指针版:
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
s_index, t_index = 0, 0
while s_index < len(s) and t_index < len(t):
if s[s_index] == t[t_index]:
s_index += 1
t_index += 1
else:
t_index += 1
return s_index == len(s)