题目分析
最长公共子序列(Longest Common Subsequence, LCS):是一个经典的问题,也是在某厂的笔试中遇到了这个问题,小伙伴们一定要会做呀。
DP
我们使用动态规划进行求解,dp[i][j]表示text1前i个字符和text2前j个字符的最长公共子序列,因为空序列和任何序列匹配都是0,初始状态i = 0或j = 0时,dp[i][j] = 0。可以得到状态转移方程。
$$ dp[i][j] = \begin{cases} dp[i - 1][j - 1] + 1 & text[i - 1] = text[j - 1] \\ max(dp[i - 1][j], dp[i][j - 1]) & text[i - 1] \ne text[j - 1] \end{cases} $$
DP的时间复杂度为$O(n^2)$,空间复杂度为$O(n^2)$。
1 | class Solution(object): |
优化DP
动态规划一般都可以进行优化,优化的方法大多是通过空间复杂度进行优化,因为DP中保存着大量的数据,可能这些数据我们在后面的计算中并不会用到。
如此题中第i次循环,只会用到第i次循环和第i - 1次循环中的内容,之前的计算结果并不会用到,因此可以只保留第i次的结果和第i - 1次的结果,这样优化DP的时间复杂度为$O(n^2)$,空间复杂度为$O(n)$。
1 | class Solution(object): |
刷题总结
LCS问题太经典了,不需要过多介绍,干就完事了。