简单的最长公共子序列(LCS)算法的C++实现,同时我将逐行解释实现细节:
#include <iostream>
#include <vector>
std::vector<std::vector<int>> initializeDpMatrix(int m, int n) {
return std::vector<std::vector<int>>(m + 1, std::vector<int>(n + 1, 0));
}
std::vector<std::vector<int>> longestCommonSubsequence(const std::vector<int>& nums1, const std::vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
// 初始化动态规划矩阵 dp
std::vector<std::vector<int>> dp = initializeDpMatrix(m, n);
// 填充动态规划矩阵 dp
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp;
}
std::vector<int> extractLCS(const std::vector<std::vector<int>>& dp, const std::vector<int>& nums1, const std::vector<int>& nums2) {
std::vector<int> lcs;
int i = nums1.size();
int j = nums2.size();
// 从动态规划矩阵 dp 反推最长公共子序列
while (i > 0 && j > 0) {
if (nums1[i - 1] == nums2[j - 1]) {
lcs.insert(lcs.begin(), nums1[i - 1]);
--i;
--j;
} else if (dp[i - 1][j] > dp[i][j - 1]) {
--i;
} else {
--j;
}
}
return lcs;
}
int main() {
std::vector<int> nums1 = {1, 2, 3, 4, 5};
std::vector<int> nums2 = {2, 4, 1, 3, 5};
// 计算最长公共子序列的动态规划矩阵
std::vector<std::vector<int>> dp = longestCommonSubsequence(nums1, nums2);
// 提取最长公共子序列
std::vector<int> lcs = extractLCS(dp, nums1, nums2);
// 输出最长公共子序列
std::cout << "Longest Common Subsequence: ";
for (int num : lcs) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
逐行解释:
-
initializeDpMatrix
: 这个函数用于初始化动态规划矩阵dp
,将其所有元素初始化为0。 -
longestCommonSubsequence
: 这个函数计算最长公共子序列的动态规划矩阵dp
。通过填充这个矩阵,我们可以找到最长公共子序列的长度。 -
extractLCS
: 这个函数用于从动态规划矩阵dp
中提取最长公共子序列。通过反向遍历矩阵,我们可以重建最长公共子序列的具体元素。 -
main
函数:在主函数中,我们定义了两个整数向量nums1
和nums2
,然后调用上述两个函数计算最长公共子序列的动态规划矩阵和提取最长公共子序列。最后,输出最长公共子序列。