【Leetcode每日笔记】392. 判断子序列(Python)

文章目录

  • 题目
  • 解题思路
    • 双指针
    • 动态规划
      • 状态定义
      • 状态转移方程
  • 代码

题目

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

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

进阶:

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

示例 1:

输入:s = “abc”, t = “ahbgdc” 输出:true

示例 2:

输入:s = “axc”, t = “ahbgdc” 输出:false

提示:

0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

解题思路

双指针

初始化两个指针 i和 j,分别指向 s 和 t的初始位置。每次贪心地匹配,匹配成功则 i 和 j同时右移,匹配 s 的下一个位置,匹配失败则 j 右移,i 不变,尝试用 t 的下一个字符匹配 s。

最终如果 i 移动到 s 的末尾,就说明 s是 t 的子序列。

动态规划

状态定义

dp[i][j]表示从位置i开始字符j第一次出现的位置,0

状态转移方程

d p [ i ] [ j ] = { i t[i]=j f [ i + 1 ] [ j ] t[i]!=j ( 0 ≤ i ≤ l e n ( s ) , 0 ≤ j ≤ l e n ( t ) ) d p [ l e n ( s ) ] [ l e n ( j ) ] = [ l e n ( t ) ∗ 26 ] 表 示 该 位 置 后 没 有 字 符 j dp[i][j]= \begin{cases} i& \text{t[i]=j}\\ f[i+1][j]& \text{t[i]!=j} \end{cases} (0≤i≤len(s),0≤j≤len(t)) \\ dp[len(s)][len(j)] =[len(t) * 26]表示该位置后没有字符j dp[i][j]={ if[i+1][j]t[i]=jt[i]!=j(0ilen(s),0jlen(t))dp[len(s)][len(j)]=[len(t)26]j

代码

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        i,j = 0,0
        if not s:
            return True
        elif not t:
            return False
        while True:
            if j == len(t):
                return False
            if s[i] == t[j]:
                i += 1
            j += 1
            if i ==len(s):
                return True
class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        n, m = len(s), len(t)
        f = [[0] * 26 for _ in range(m)]
        f.append([m] * 26)

        for i in range(m - 1, -1, -1):
            for j in range(26):
                f[i][j] = i if ord(t[i]) == j + ord('a') else f[i + 1][j]
        
        add = 0
        for i in range(n):
            if f[add][ord(s[i]) - ord('a')] == m:
                return False
            add = f[add][ord(s[i]) - ord('a')] + 1
        
        return True

你可能感兴趣的:(LeetCode一周一结,#,动态规划,指针,python,leetcode,数据结构,动态规划)