一、题目描述
给定两个字符串 text1
和 text2
,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回 0
。
一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,"ace"
是 "abcde"
的子序列,但 "aec"
不是 "abcde"
的子序列。
两个字符串的公共子序列是这两个字符串所共同拥有的子序列。
示例 1:
输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3。
示例 2:
输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3。
示例 3:
输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0。
二、题解
通过动态规划求解,从前向后依次求解每个子序列的最长公共子序列长度即可,时间复杂度和空间复杂度均为 O ( m × n ) O(m \times n) O(m×n)。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
/* dp[i][j]表示text1前i个字符组成的序列和text2前j个字符组成的序列的最长公共子序列 */
vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
/* 从左到右从上到下递推 */
for (int i = 0; i < text1.size(); i++) {
for (int j = 0; j < text2.size(); j++) {
if (text1.at(i) == text2.at(j)) {
dp.at(i + 1).at(j + 1) = dp.at(i).at(j) + 1; // 匹配成功长度加一
} else {
dp.at(i + 1).at(j + 1) = max(dp.at(i).at(j + 1), dp.at(i + 1).at(j)); // 匹配失败直接忽略新添加的字符
}
}
}
return dp.at(text1.size()).at(text2.size());
}
};