代码随想录算法训练营Day55 (Day 54休息) | 动态规划(15/17) LeetCode 392.判断子序列 115.不同的子序列

继续子序列的练习!

第一题

392. Is Subsequence

Given two strings s and t, return trueif sis a subsequence of t, or falseotherwise.

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 "++a++ b++c++ d++e++" while "aec" is not).

首先想到双指针的解法,复杂度为O(n),也能接受。不过既然在练习动态规划,就还是按照动态规划的思路去解。

在确定递推公式的时候,首先要考虑如下两种操作,整理如下:

  • if (s[i - 1] == t[j - 1])
    • t中找到了一个字符在s中也出现了
  • if (s[i - 1] != t[j - 1])
    • 相当于t要删除元素,继续匹配

if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1

if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];

python 复制代码
class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        dp = [[0] * (len(t)+1) for _ in range(len(s)+1)]
        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]
        if dp[-1][-1] == len(s):
            return True
        return False

第二题

115. Distinct Subsequences

Given two strings s and t, return the number of distinct subsequences of swhich equalst.

The test cases are generated so that the answer fits on a 32-bit signed integer.

这道题双指针就没法做了,只能用动态规划。

递推公式为:dp[i][j] = dp[i - 1][j];

从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; 和 dp[i][j] = dp[i - 1][j]; 中可以看出dp[i][j] 是从上方和左上方推导而来,那么 dp[i][0] 和dp[0][j]是一定要初始化的。

python 复制代码
class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        n1, n2 = len(s), len(t)
        if n1 < n2:
            return 0

        dp = [0 for _ in range(n2 + 1)]
        dp[0] = 1

        for i in range(1, n1 + 1):

            prev = dp.copy()
            end = i if i < n2 else n2
            for j in range(1, end + 1):
                if s[i - 1] == t[j - 1]:
                    dp[j] = prev[j - 1] + prev[j]
                else:
                    dp[j] = prev[j]
        return dp[-1]
相关推荐
Peter·Pan爱编程1 小时前
10. new_delete 不是 malloc_free 的包装
c++·人工智能·算法
故事和你912 小时前
洛谷-【动态规划1】动态规划的引入2
开发语言·数据结构·c++·算法·动态规划·图论
重生之我是Java开发战士2 小时前
【动态规划】背包问题:完全背包,二位费用的背包问题,似包非包
算法·动态规划
LabVIEW开发3 小时前
LabVIEW实现FDTD 电磁仿真
算法·labview·labview知识·labview功能·labview程序
Together_CZ3 小时前
DTSemNet :Vanilla Gradient Descent for Oblique Decision Trees——用于倾斜决策树的普通梯度下降
算法·决策树·机器学习·vanilla·gradient·dtsemnet·用于倾斜决策树的普通梯度
一条大祥脚3 小时前
ABC459 贪心构造|树形DP|组合数学|贪心|单调栈|势能|前缀和
算法·深度优先
灰灰勇闯IT4 小时前
DeepEP:MoE 推理的 AllToAll 通信瓶颈怎么解
算法·cann
一行代码一行诗++4 小时前
goto语句
java·开发语言·算法
汉克老师4 小时前
GESP5级C++考试语法知识(十七、二分算法提高篇(二))
c++·算法·二分算法·gesp5级·gesp五级·二分算法易错点
叶小鸡4 小时前
小鸡玩算法-力扣HOT100-动态规划(下)
算法·leetcode·动态规划