代码随想录第55天|392. 判断子序列、115. 不同的子序列

54 阅读1分钟

392. 判断子序列

doc reading

相等的字符,就应该是左上角位置状态记录值 + 1. 如果s[i]和t[j]不相等,根据实际意义,就应该是s[:i]与t[:j-1]的公共字数结果。

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        dp = [[0] * (len(t) + 1) for _ in range(len(s) + 1)]
        s = list(s)
        t = list(t)
        for i in range(1, len(s) + 1):
            for j in range(1, len(t) + 1):
                if s[i - 1] == t[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = dp[i][j - 1]
        # print(dp)
        return dp[-1][-1] == len(s)

这个和之前的最长公共序列不同,因为我们只能跳过t序列,而不能跳过s序列中的字符。 而公共子序列的递推式是:

if s[i-1] == t[j-1]:
    dp[i][j] = dp[i - 1][j - 1] + 1
else:
    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

很明显就是跳过两个序列的字符。

115. 不同的子序列

1. doc reading

相等也不一定选,也有可能不选择当前字符s[i],而选择s[i-1]。

class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        s = list(s)
        t = list(t)

        dp = [[0] * (len(t) + 1) for _ in range(len(s) + 1)]

        for idx in range(len(s) + 1):
            dp[idx][0] = 1 #空字符串也匹配
        
        for i in range(len(s) + 1):
            for j in range(len(t) + 1):
                if s[i - 1] == t[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
                else:
                    dp[i][j] = dp[i - 1][j]
        # print(dp)
        return dp[-1][-1]