最长公共子序列(LCS)
目录
一、题型解释
最长公共子序列(Longest Common Subsequence,LCS)是求解两个序列中共同存在的最长子序列的问题。子序列不要求连续,但顺序必须一致。常见题型:
-
基础问题:计算两个序列的LCS长度(如
"ABCBDAB"
和"BDCAB"
的LCS长度为4)。 -
输出具体LCS:返回所有可能的LCS字符串(如
"BCAB"
和"BDAB"
)。 -
变种问题:
-
最长公共子串(连续子序列)。
-
多序列LCS:三个或更多序列的LCS。
-
空间优化:减少内存占用(如从二维数组优化为一维数组)。
-
二、例题问题描述
例题1:输入 s1 = "ABCBDAB"
,s2 = "BDCAB"
,输出LCS长度 4
。
例题2:输入 s1 = "abcde"
,s2 = "ace"
,输出LCS字符串 "ace"
。
例题3:输入 s1 = "ABCDGH"
,s2 = "AEDFHR"
,输出LCS长度 3
(对应 "ADH"
)。
例题4:输入 s1 = "abcabc"
,s2 = "acbabc"
,输出所有可能的LCS(如 "ababc"
和 "acabc"
)。
三、C语言实现
解法1:动态规划(基础版,难度★)
通俗解释:
-
填表格法:构建一个二维表格,每个格子记录当前位置的LCS长度,像搭积木一样逐步推导。
c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 100
int lcs(char *s1, char *s2) {
int m = strlen(s1), n = strlen(s2);
int dp[MAX_LEN][MAX_LEN] = {0}; // dp[i][j]表示s1前i个和s2前j个的LCS长度
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {