系列文章目录
【动态规划】最长子串问题汇总(五)最长连续公共子序列
【动态规划】最长子串问题汇总(六)归纳对比
目录
前言
在练习算法的过程中,发现各种子序列问题容易混淆,问题通常是连续,公共,上升(递增)三词随意组合,本系列就最长子串(子序列)问题进行归纳对比
一、题目描述
给定两个字符串(仅包含小写字母),求其最长连续公共子序列长度
二、输入输出样例
输入是两个仅包含小写字母的字符串(数组同理),输出是一个正整数,表示最长连续公共子序列的长度
输入:s1 = "abcdefg", s2="acdefiok"
输出:4
此样例中,最长公共子序列是 "acdef",但最长连续公共子序列是 "cdef"
三、算法分析
if (s1[i-1] ! = s2[j-1]) dp[i][j]=0
最大个数用 cnt 记录,所以当出现字符不相等时,说明不连续了,直接从 0 开始计数
当 cnt 被更新时,把下标赋给 idx,此时 idx 表示当前最长连续公共子序列的最后1个字符的下标
int getLength(string s1,string s2){
int m=s1.size(),n=s2.size(); //取字符串长度
vector<vector<int>> dp(m+1,vector<int>(n+1,0)); //开辟dp[m+1][n+1]
int cnt=0,idx=0;//个数,连续公共子序列终止的下标
for(int i=1;i<=m;i++){ //遍历 s1
for(int j=1;j<=n;j++){ //遍历 s2
/*------------------区别部分------------------*/
if(s1[i-1]==s2[j-1]){ //当前位置字符相同
dp[i][j]=dp[i-1][j-1]+1;
if(cnt<=dp[i][j]){ //更新个数
idx=i; // <=是保证在最长连续公共子序列不唯一的情况下,输出最后一个
cnt=dp[i][j];
}
}
else{ //字符不相同,出现不同直接清 0(因为要求连续)
dp[i][j]=0;
}
/*------------------区别部分------------------*/
}
}
return cnt;
}
如果题目还要求输出最长连续公共子串。且如果不唯一,则输出 s1 中的最后一个
idx-=cnt; //原来的 idx是连续公共子序列最后一个字符的下标
while(cnt){
char c=s1[idx];
idx++; cnt--;
cout<<c;
}
输入:s1 = "abcdefg", s2="acdefiok"
输出:ecdf
/*------------------区别部分------------------*/
其中的代码是各种最长子串(子序列)问题的具体区别
/*------------------区别部分------------------*/