最长公共子序列
最长公共子序列的问题很简单,就是在两个字符串中找到最长的子序列,这里明确两个含义:
- 子串:表示连续的一串字符 。
- 子序列:表示不连续的一串字符。
所以这里要查找的是不连续的最长子序列,
动态规划
这里为什么要使用动态规划可以说一下,简单来说动态规划是为了降低时间复杂度的一种算法,申请一个额外空间,来保存每一个步骤的结果,最后从这些结果中找到最优的解。
这里有个问题就是:一般来说,当前的最优解,只与当前时刻和上一时刻有关系,和其他时刻没有关系,这样才能让动态规划发生作用,降低复杂度。
分析LCS
其实LCS看起来很麻烦,找不到思路,如果暴力破解可能要O(n^4)了,而这个题目使用动态规划的思想也非常简单,为何相比之前的问题不好找思路呢?
是因为之前的动态规划问题例如:背包问题,生产线问题,都是一维数组空间内的结果,规划到一个线性时间内,而这个题目需要O(m*n)的时间复杂度和空间复杂度。
所以其实就是进行
m*n
次对比,每次保存当前的最优解,就可以了。
代码实现分析
这里有个问题,就是我们需要的结果仅仅是长度? 还是包括这个序列串一起输出。
看下面图:
这里可以看到,我们构造的一个i*j
的矩阵,这个矩阵里的内容不但包括数值(当前结果的最优解),还包括一个方向箭头,这个代表了我们回溯的时候,需要行走的方向。
所以我们这里保存两个值,可以使用两个二维矩阵,也可以使用一个结构体矩阵。
解法分析
其实这个题目在动态规划来理解,也非常简单。一个状态转移函数。
这个非常好理解,其中一个字符串为0的时候,那么肯定是0了。
当两个字符相等的时候,这个时候很好理解,举例来说:
abcd
和 adcd
,在遍历c
的时候,发现前面只有a
相等了,也就是1.