1143. 最长公共子序列

leetcode:1143. 最长公共子序列

dp[i][j] 二维数组的动态规划
状态转移方程是:
需要注意的是,dp数组是(m+1)*(n+1), 第一行和第一列的初始状态是为0的

n = len(text1)
m = len(text2)
(0,0)(0,1)(0,2)...(0,n)
(1,0)(1,1)(1,2)...
.
.
.
(m,0)
t1 = 0
if 第i个字符和第j个字符相等:
    t1 = dp[i-1][j-1] + 1
t2 = max(dp[i-1][j], dp[i][j-1])
dp[i][j] = max(t1,t2)

以下是完整代码:

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        n = len(text1)
        m = len(text2)
        dp = [ [0]*(n+1) for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                t1 = 0
                if text2[i-1] == text1[j-1]:
                    t1 = dp[i-1][j-1] + 1
                t2 = max(dp[i-1][j], dp[i][j-1])
                dp[i][j] = max(t1,t2)
        return dp[m][n]

dfs 加去重,属于动态规划的另外一种做法

重点是找到递归子结构(状态的转移),对于去重,使用的字典的结构(也可以使用二维数组来记录状态)
递归基的处理需要注意,我之前只考虑(0,1)(1,0)(0,0)的情况,然后没考虑(2,0)(3,0)等这种情况,导致撑爆了递归使用的栈,正确的做法是:

if i < 0 or j <0:
	return 0

最后传入参数的时候,是len(text1)-1, len(text2)-1 ,要减一

_dfs(len(text1)-1, len(text2)-1)

还有一个情况是,执行下一行时,报错res3,没有定义

res =max(res1,res2,res3); dict1[(i,j)] = res

原来res是在if 判读语句中定义的,需要在外面初始化一下
以下是代码:

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        dict1 = {}
        def _dfs(i,j):
            if i < 0 or j <0:
                return 0
            # res1 = 0
            # res2 = 0
            
            if (i-1,j) in dict1.keys():
                res1 = dict1[(i-1,j)]
            else: res1 = _dfs(i-1,j); dict1[(i-1,j)] = res1

            if (i,j-1) in dict1.keys():
                res2 = dict1[(i,j-1)]
            else: res2 = _dfs(i,j-1); dict1[(i,j-1)] = res2

            res3 = 0
            # print("i,j ",i, j)
            if text1[i] == text2[j]:
                if (i-1,j-1) in dict1.keys():
                    res3 = dict1[(i-1,j-1)]+1
                else:
                    res32 = _dfs(i-1,j-1); dict1[(i-1,j-1)] = res32
                    res3 = res32 + 1 ; 
            res =max(res1,res2,res3); dict1[(i,j)] = res
            return res
        return _dfs(len(text1)-1, len(text2)-1)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值