LeetCode 115.不同的子序列

LeetCode 115.不同的子序列

详细题目

题目分析

题目大致意思就是在主串中找不同子串的数量。思路比较明显是动态规划。
d p ( i , j ) dp(i, j) dp(i,j)表示 S [ i : ] S[i: ] S[i:] T [ j : ] T[j: ] T[j:]出现的次数(S为主串,T为匹配串)。则递推式有:

d p ( i , j ) = { d p ( i + 1 , j ) , if S[i] == T[j] d p ( i + 1 , j + 1 ) + d p ( i + 1 , j ) , if S[i] != T[j] dp(i,j) = \begin{cases} dp(i + 1, j), & \text{if S[i] == T[j]} \\ dp(i + 1,j + 1) + dp(i + 1, j), & \text{if S[i] != T[j]} \end{cases} dp(i,j)={dp(i+1,j),dp(i+1,j+1)+dp(i+1,j),if S[i] == T[j]if S[i] != T[j]
结束条件: d p ( i , j ) = { 1 , if j >= len(T) 0 , if i >= len(S) dp(i,j) = \begin{cases} 1, & \text{if j >= len(T)} \\ 0, & \text{if i >= len(S)} \end{cases} dp(i,j)={1,0,if j >= len(T)if i >= len(S)
(注意结束条件的顺序)
原问题即dp(0,0),动态规划的实现,笔者用相对容易理解的递归实现(注意记忆化)的,当然也可以用扫描数组的形式去实现。

代码

class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        global d
        d = [[-1 for _ in range(len(t))] for _ in range(len(s))]
        def dp(i, j):
            if j >= len(t):
                return 1
            if i >= len(s):
                return 0
            if d[i][j] != -1:
                return d[i][j]
            
            if s[i] == t[j]:
                ret = dp(i + 1, j + 1) + dp(i + 1, j)
            else:
                ret = dp(i + 1, j)
            
            d[i][j] = ret
            return ret
        
        return dp(0, 0)
吐槽

LeetCode上的某些题解非要把动态规划的两种形式分开来写,还说成是分治。啧啧啧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值