question:
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
Input
第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)
Output
输出最长的子序列,如果有多个,随意输出1个。
Sample Input
abcicba
abdkscab
Sample Output
abca
分析,建立递推关系
已知两个字符串S 0 S1…Si…Sn-1和 T0 T1…Tj…Tm-1、
(1)当Si=Tj时
S0 S1…Si-1Si和 T0 T1…Tj-1Tj的LCS长度=
S0 S1…Si-1和 T0 T1…Tj-1LCS的长度+1
(2)当Si!=Tj时
S0 S1…Si-1Si和 T0 T1…Tj-1Tj的LCS长度=
S0 S1…Si-1和 T0 T1…Tj-1Tj的LCS长度与
S0 S1…Si-1Si和 T0 T1…Tj-1的LCS长度中较大的一个
思路:
1.定义dp[i][j]作为二维数组的一个元素,用 它来记录:
s中,S0 S1…Si-1和 T0 T1…Tj-1这两个子串的LCS
2.根据前面的递推关系式以及dp数组的含义有:
(1)当Si = Tj时
dp[i+1][j+1]=dp[i][j]+s[i];
(2)当Si != Tj时
dp[i+i][j+i]=max(dp[i][j+1], dp[i+1][j])
例如: s= "abcicba"
t= " abdkscab"
t\s | 1(a) | 2(b) | 3(c) | 4(i) | 5(c) | 6(b) | 7(a) | |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
1(a) | 0 | a | a | a | a | a | a | a |
2(b) | 0 | a | ab | ab | ab | ab | ab | ab |
3(d) | 0 | a | ab | ab | ab | ab | ab | ab |
4(k) | 0 | a | ab | ab | ab | ab | ab | ab |
5(s) | 0 | a | ab | ab | ab | ab | ab | ab |
6(c) | 0 | a | ab | abc | abc | abc | abc | abc |
7(a) | 0 | a | ab | abc | abc | abc | abc | abca |
8(b) | 0 | a | ab | abc | abc | abc | abcb | abcb |
代码实现:
class Solution{
public:
string lcs(string s,string t){
int len_s=s.length();
int len_t=t.length();
string dp[len_s+1][len_t+1];
for(int i=0;i<len_t;i++){
for(int j=0;j<len_s;j++){
if(s[i]==t[j])
dp[i+1][j+1]=dp[i][j]+s[i];
else if(dp[i+1][j].length()>dp[i][j+1].length())
dp[i + 1][j + 1] = dp[i + 1][j];
else
dp[i + 1][j + 1] = dp[i][j + 1];
}
}
return dp[-1][-1];
}
};