1143. 最长公共子序列

题目描述

思路
这是一道非常经典的二维动态规划应用问题。我们都知道应该使用二维动态规划来解决这个问题,但是好像我没有仔细思考过为什么应该使用二维动态规划来解决这个问题,因此在此分析一下。
如果不使用动态规划,我们自然想到最坏的情况就是使用暴力枚举来解决这个问题,问题仍然在于不能够复用之前已经求过的公共子序列。因此我们定义一个二维数组dp,dp[i][j]的含义就是text从0...i的子串和text2从0...j的子串的最长公共子序列的长度。
显然,如果存在text1[i] == text2[j]的情况,则dp[i][j] = dp[i - 1][j -1] + 1,即如果当前两个串当中遍历到的字符是相等的,则0...i与0...j子串的最长公共子序列的长度是0...i - 1和0...j - 1串的结果加上1;而如果text[1] != text2[j],则dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]),意味着如果当前text1[1] != text[2],则不能增加0...i与0...j子串的最长公共子序列的长度,该位置的最长公共子序列长度应该取可能的最大值。
基于以上思路,我们便可以写代码解决问题了。
Golang 代码
go
func longestCommonSubsequence(text1 string, text2 string) int {
m, n := len(text1), len(text2)
dp := make([][]int, m + 1)
for i := 0; i <= m; i ++ {
dp[i] = make([]int, n + 1)
}
for i := 1; i <= m; i ++ {
for j := 1; j <= n; j ++ {
if text1[i - 1] == text2[j - 1] {
dp[i][j] = dp[i - 1][j - 1] + 1
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])
}
}
}
return dp[m][n]
}