动态规划面试宝典
卢誉声
Autodesk 首席工程师
9629 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 23 讲
动态规划面试宝典
15
15
1.0x
00:00/00:00
登录|注册

09|子序列问题:详解重要的一大类动态规划问题

你好,我是卢誉声。
我们曾在上一课中提到,有两类重要的动态规划问题需要掌握,其中一个是子数组问题,另一个是子序列问题。今天,我们将深入讲解动态规划中的另一个经典问题,即子序列问题。
相较于子数组问题而言,子序列问题要更复杂一些,这是由子序列的特性决定的。不过有一点比较类似,那就是我们仍然需要小心定义备忘录结构和其对应值的含义。
你应该注意到了,我们把子数组问题和子序列问题放在一块儿讲,这意味着它们之间是有联系的。因此,在开始今天的课程前,我提出这样一个问题:子数组和子序列问题在求解时有什么异同呢?
接下来就让我们带着这个问题,开始今天的学习之旅吧。

什么是子序列问题?

类似的,我们要明确一下什么是动态规划中的子序列问题。首先,相较于子数组问题而言,子序列问题要更复杂一些。这是因为,子数组问题是连续的,而子序列问题是不连续的。比如说字符串 “I wanna keep a giraffe in my backyard” 的一种子序列就可以是 “Igbackd”。
因此,你可以看到,子序列不再要求答案是一个连续的串。即便用穷举的思路求解问题,我们都不一定知道该从何下手解决。特别的,当涉及到两个数组或字符串作为输入的情况时,如果没有处理经验,真的不容易想到解法。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了动态规划中的子序列问题,特别是最长回文子序列和最长公共子序列问题。文章首先介绍了子序列问题的复杂性,以及动态规划在解决这类问题时的重要性。针对最长回文子序列问题,文章详细分析了状态转移方程的设计和决策过程,并给出了Java和C++的代码实现。此外,文章还介绍了最长公共子序列问题的算法问题分析和状态转移方程的设计。通过对备忘录的定义和状态转移方程的解释,读者能够清晰地理解问题的求解思路和方法。整体而言,本文内容深入浅出,适合技术人员学习和应用。 文章通过具体的Java和C++代码实现了最长公共子序列问题的解决方案,展示了动态规划在实际问题中的应用。此外,文章还提到了动态规划中子序列问题的复杂性,以及动态规划在解决这类问题时的重要性。通过对备忘录的定义和状态转移方程的解释,读者能够清晰地理解问题的求解思路和方法。文章还对最长公共子序列问题的算法问题分析和状态转移方程的设计进行了介绍。整体而言,本文内容深入浅出,适合技术人员学习和应用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《动态规划面试宝典》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • webmin
    空间复杂度的压缩状态,dp[i][j]中的j只有两种状态,当前和前一个,使用j%2和j-1%2就可以在两者之间切换。i不可以压缩,因为内层每一轮循环,都要用到之前所有行的两个列状态,这两个列状态是只之前推到出的,不是本轮内层循环推到出的。 int getLongestCommonSubsequence(String text1, String text2) { int m = text1.length(), n = text2.length(); int[][] dp = new int[m + 1][2]; for (int[] row: dp) { Arrays.fill(row, 0); } for (int j = 1; j <= n; j++) { int a = j % 2; int b = (j - 1) % 2; for (int i = 1; i <= m; i++) { if (text2.charAt(j - 1) == text1.charAt(i - 1)) { dp[i][a] = dp[i - 1][b] + 1; } else { dp[i][a] = Math.max(dp[i - 1][a], dp[i][b]); } } } return dp[m][n%2]; }

    作者回复: 没有问题,正确。顶上去,赞。

    2020-10-03
    6
  • 我来也
    又学到了新知识,开心。 老师的第一个状态转移方程与实际代码不匹配,代码中是正确的。 dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]); 而dp方程是 dp[i][j] = Math.max(dp[i+1][j], dp[i][j+1]);

    作者回复: 的确状态转移方程不一致,已修正。感谢反馈。

    2020-10-07
    4
  • 振兴
    if(text2[j-1]==text1[i-1]),这个不对吧,不是应该判定text2[j]==text1[i]吗?这里不太懂为什么减1,麻烦老师解说一下

    作者回复: 因为0是一个空状态,遍历是[1,i]和[1,j]。所以实际比较的时候在索引上都需要减去1。

    2021-10-08
    2
  • 老师您好,在第二个问题求解最长公共子序列中,开始定义的dp[i][j]表示text1[0][i]与text2[0][j]的最长公共子序列,但是实际代码中返回的是dp[m][n],这与预定义的不符合吧,text1[m]与text2[n]应该越界了吧. 而且我们定义dp数组时,也是添了一行一列,不如定义dop[i][j]为text1的前i个字符和text2的前j个字符所对应的最长公共子序列,既然dp添了一行一列,那么text1与text2也在开头添一个字符,这样所有的下标都是从1开始,会不会好一点. 在处理动规问题时,下标从0开始还是从1开始,我觉得对我来说也是一个很大的坑,容易陷进去,希望老师后续可以讲一下这一点的注意事项.

    作者回复: 你说的对。 改成这样比较容易理解: text1[i-1] == text2[j-1] text1[i-1] != text2[j-1]  

    2020-10-02
    1
  • 绘世浮夸 つ
    在最长公共子序列的画的表中的dp[2][4]不应该是2嘛,ad和abcde中最长的ad都只有2,怎么来的3啊老师,是错了还是什么

    作者回复: 文中的确是说这里dp[2][4]的值是2,然后dp[3][5]的值是3,可以再仔细看一下。

    2022-03-02
  • Sam Fu
    讲算法还是视频形式好

    作者回复: 以后会考虑通过更加丰富的方式来讲解算法。

    2021-10-25
    2
  • Shine
    在最长回文子序列问题中,对于dp[i][j], 当i>j时,都是无效子串吧,值都为0,遍历的时候i是不是只要从i-2开始遍历就行

    作者回复: 这里j应该从i+1开始遍历。

    2021-05-17
  • Geek_531e37
    for (int i = n-1; i >= 0; i--) { for (int j = i+1; j < n; j++) ,这两个for循环,我有点看不懂???

    作者回复: 要求解此问题,从我们构建出来的状态转移方程可以看出,其包含了两个状态,在正文中可以看到我们最终构建的备忘录是二维的,因此为了能够到达所有状态的计算位,我们需要两层for循环来进行遍历、计算。

    2021-04-21
  • Geek_531e37
    当s[i]!=s[j],为什么要向前后一步呢?为什么最终结果会在左上角获取?

    作者回复: 最终结果在右上角,其原因在于备忘录的定义,以及计算方向的设计问题。

    2021-04-21
  • 猫头鹰爱拿铁
    可以空间优化,只需要一维数组。划好状态矩阵,可知下一行状态就是上一行和左边的数据分析后的结果,所以需要临时变量存储左上角的状态。具体代码如下。 public int longestCommonSubsequence(String text1, String text2) { int n1 = text1.length(); int n2 = text2.length(); int[] dp = new int[n1 + 1]; for (int i = 0; i < n1 + 1; i++) { dp[i] = 0; } for (int i = 1; i < n2 + 1; i++) { int temp = 0; int cp = 0; for (int j = 1; j < n1 + 1; j++) { if (text1.charAt(j - 1) == text2.charAt(i - 1)) { temp = cp + 1; } else { temp = Math.max(dp[j - 1], dp[j]); } cp = dp[j]; dp[j] = temp; } } return dp[n1]; }

    作者回复: 没有问题。顶上去!

    2020-12-03
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部