使用动态规划解最长子串

题目来源:牛客网第127题

给定两个字符串str1和str2,输出两个字符串的最长公共子串

题目保证str1和str2的最长公共子串存在且唯一。

输入:“1AB2345CD”,“12345EF”

返回值:“2345”

简单思路

最简单的想法是从第一个开始遍历,用i表示第一个字符串的索引, j 表示第二个字符串的索引,遍历到两个串中的相同字母时,使用count计数,找到该位置起最长的连续同样字母的计数,即 i + count, j + count.这样做可以解出来,但是耗时较长,因为每次遇见相同的字母都需要从1开始遍历,无法利用之前走过的步骤的解

动态规划解:

使用dp[i][j]表示在str1中的第i个字符,对应str2中的第j个字符

如果不相等,dp[i][j] = 0, 如果相等,等于两个字符串的前一个索引的值 +1

可以得到下面的递推公式:

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

遇到的问题:

  1. 发现牛客网不支持numpy,只能使用原生库生成list二维数组

  2. 在使用list过程中,刚开始定义的二维数组是使用 list_two = [[0] * 3] * 3, 实际运行过程中,发现使用 dps[i+1][j+1]赋值操作无效,查询知乎解答后发现是浅拷贝问题,改为 list_three = [[0 for i in range(3)] for j in range(3)]后可以啦

完整代码:

```
class Solution:
    def LCS(self , str1: str, str2: str) -> str:
        # write code here
        l1 = len(str1) + 1
        l2 = len(str2) + 1
        # count the number of str
        count = 0
        # save the result str
        position = 0
        # 深拷贝和浅拷贝
        dps = [[0 for i in range(l2)] for j in range(l1)]
        for i in range(0, l1-1):
            for j in range(0, l2-1):
                if str1[i] == str2[j]:
                    print(dps)
                    dps[i+1][j+1] = dps[i][j] + 1
                    print(dps[i][j], count, dps[i+1][j+1])
                    if count < dps[i+1][j+1]:
                        count = dps[i+1][j+1]
                        position = i
                else: 
                    dps[i+1][j+1] = 0
        
        return str1[position - count + 1 : position + 1]
```

后续优化:

可以将二维数组改为一维数组, 节省空间

算法复杂度和动态规划对比分析,后续博客陆续补充

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值