算法day55|392,115

392.判断子序列

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        #定义dp数组,dp[i][j],i为s,j为t
        dp = [[0 for _ in range(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

dp数组的含义dp[i][j]

i-1的字符串s的子序列。j-1的字符串t的子序列。dp[i][j]代表相同子序列的长度。

递归公式

分两种情况:当s[i-1] == t[j-1]的时候,dp[i-1][j-1]前面的长度的集合+1

当s[i-1] != t[j-1]的时候,删除t,那么剩下的就是s-1和t-2 开始比较,dp= dp[i][j-1]

初始化

初始化为0,因为有可能没有相同子序列。

如果最后的长度与s字符串的相等的话,说明是true

代码随想录

二刷(未ac)

var isSubsequence = function(s, t) {
    // 以i-1和j-1为结尾的字符串的个数为dp[i][j]
    let dp = new Array(s.length+1).fill(0).map(()=>new Array(t.length+1).fill(0))
    for(let i = 1;i<=s.length;i++){
        for(let j = 1;j<=t.length;j++){
            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[s.length][t.length] === s.length){
        return true
    }
    return false
    
};

115.不同的子序列

dp数组的定义

这个dp数组的定义都很难。

dp[i][j]是以i-1为结尾的s子序列中出现以j-1为结尾为1的t的个数为dp[i][j]

就是说,假设s 中"b"匹配t中的“b",看有多少个。

递归公式

如果s[i-1]和t[j-1]相等,

可以由两个部分组成,第一个部分是使用s[i-1]来匹配。

dp[i][j] = dp[i-1][j-1]

为什么不是不用加一呢?????不是又匹配上了吗?

第二个是不使用s[i-1]来匹配。dp[i-1][j]跳了下一个匹配。

s[i-1]和t[j-1]不相等:

只能跳下一个匹配

所以还是dp[i][j] = dp[i-1][j]

初始化

dp[i][0]代表用空来匹配s,所以都为1.

dp[0][j]代表t匹配空,所以都是为0

dp[0][0],空配空,所以为1

class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        #dp数组,dp[i][j]
        dp = [[0]*(len(t)+1) for _ in range(len(s)+1)]
        #初始化
        for i in range(len(s)):dp[i][0] = 1
        for j in range(1,len(t)):dp[0][j] = 0
        for i in range(1,len(s)+1):
            for j in range(1,len(t)+1):
                if s[i-1] == t[j-1]:
                    #用s[i-1]来匹配,和不用s[i-1]来匹配
                    dp[i][j] = dp[i-1][j-1]+dp[i-1][j]
                else:
                    dp[i][j] = dp[i-1][j]
        return dp[-1][-1]

代码随想录

二刷(未ac)

var numDistinct = function(s, t) {
    // 以i-1为结尾的t序列有dp[i]种方法
    let dp = new Array(s.length+1).fill(0).map(()=>new Array(t.length+1).fill(0))
    // 初始化
    for(let i = 0;i<s.length;i++){
        dp[i][0] = 1
    }
    for(let i = 1;i<=s.length;i++){
        for(let j = 1;j<=t.length;j++){
            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]
            }
        }
    }
    return dp[s.length][t.length]
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值