题目描述
给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如过最长公共子序列为空,则输出-1。
输入描述:
输出包括两行,第一行代表字符串str1,第二行代表str2。(1≤length(str1),length(str2)≤5000)
输出描述:
输出一行,代表他们最长公共子序列。如果公共子序列的长度为空,则输出-1。
示例1
输入
1A2C3D4B56
B1D23CA45B6A
输出
123456
说明
"123456"和“12C4B6”都是最长公共子序列,任意输出一个。
备注:
时间复杂度O(n∗m),空间复杂度O(n∗m)。(n,m分别表示两个字符串长度)
//dp[i][j]的含义是s[0..i]与s[0..j]的最长公共子序列的长度
#include<bits/stdc++.h>
using namespace std;
int main(){
string s1,s2;
cin>>s1>>s2;
int m=s1.size();
int n=s2.size();
vector<vector<int>> dp(m,vector<int>(n,0));
if(s1[0]==s2[0]){
dp[0][0]=1;
}
for(int i=1;i<m;i++){
dp[i][0]=max(dp[i-1][0],(s1[i]==s2[0] ? 1 : 0));
}
for(int j=1;j<n;j++){
dp[0][j]=max(dp[0][j-1],(s1[0]==s2[j] ? 1 : 0));
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(s1[i]==s2[j]){
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
}
}
string res="";
int count=dp[m-1][n-1];
int i=m-1,j=n-1;
while(count>0){ //构建res序列
if(i>0 && dp[i][j]==dp[i-1][j]){
i--;
}else if(j>0 && dp[i][j]==dp[i][j-1]){
j--;
}else{ //dp[i][j]==dp[i-1][j-1]+1 s1[i]==s2[j]
res=s1[i]+res;
i--;
j--;
count--;
}
}
if(res.size()){
cout<<res<<endl;
}else{
cout<<-1<<endl;
}
return 0;
}