字符串的最长公共子序列

本文详细解析了最长公共子序列(LCS)问题,介绍了如何使用动态规划来解决这一经典算法问题。通过定义dp数组、确定base case和状态转移方程,逐步阐述了动态规划解决字符串子序列问题的思路。
摘要由CSDN通过智能技术生成

审题
最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经典的面试题目,因为它的解法是典型的二维动态规划,大部分比较困难的字符串问题都和这个问题一个套路,比如说编辑距离。而且,这个算法稍加改造就可以用于解决其他问题,所以说LCS算法是值得掌握的。

所谓子序列,就是要保留原始顺序,但可以是不连续的。审题之后你可能会有疑问,这个问题为啥就是动态规划来解决呢?因为子序列类型的问题,穷举出所有可能的结果都不容易,而动态规划算法做的就是穷举 + 剪枝,它俩天生一对儿。所以可以说只要涉及子序列问题,十有八九都需要动态规划来解决。

动态规划思路
第一步,一定要明确 dp 数组的含义。
对于两个字符串的动态规划问题,套路是通用的。

比如说对于字符串 s1 和 s2,它们的长度分别是 m、n,一般来说都要构造一个这样的 DP table:int[][] dp = new int[m+1][n+1]。

这里为什么要加1,原因是你可以不加1,但是不加1你就会用其它限制条件来确保这个index是有效的,而当你加1之后你就不需要去判断只是让索引为0的行和列表示空串。

第二步,定义 base case
我们专门让索引为0的行和列表示空串,dp[0][…] 和 dp[…][0] 都应该初始化为0,这就是base case。

第三部,找状态转移方程
这是动态规划最难的一步,我们来通过案例推导出来。

对于 text1:abcde 和 text2:ace 两个字符串,我们定义两个指针进行遍历 i 和 j。

遍历 text1 长度为 m,定义指针 i,从 0~m。固定 i 指针(i == 1)位置,接下来开始遍历 text2 长度为 n,定义指针 j,从 0~n。

在这里插入图片描述

第一次遍历 i = 1, j = 1,两个a相同所以 dp[1][1] = 1
第二次遍历 i = 1, j = 2,a与c不等,也不能是0,这里需转换成 a 与 ac 最长子序列,这里需要把之前的关系传递过来,所以dp[1][2] = 1
第三次遍历 i = 1, j = 3,a与e不相同,把之前的关系传递过来,所以dp[1][3] = 1
text2:ace 已经走完来第一轮,接下来text1:abcde 走到来b字符。

第四次遍历 i = 2, j 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值