5、最长公共子序列(LongestCommonSubsequence)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/SinclairWang/article/details/102613977

问题描述

求两个长度分别为m和n的字符串A、B的最长公共子序列。
A:a0a1a2…am-1
B:b0b1b2…bn-1

思路

构造一个大小为(m+1)*(n+1)的二维数组dp
dp[i][j] 表示a0a1a2…ai-1 和 b0b1b2…bj-1 两个字符串的最大公共子序列

状态转移方程

d p [ i ] [ j ] = { 0 if i=0 or j=0 d p [ i 1 ] [ j 1 ] + 1 if a[i-1]=b[j-1]  m a x ( d p [ i 1 ] [ j ] , d p [ i ] [ j 1 ] ) if a[i-1]!=b[j-1] dp[i][j]= \begin{cases}0 & \text {if i=0 or j=0} \\ dp[i-1][j-1]+1 & \text{if a[i-1]=b[j-1] } \\ max(dp[i-1][j],dp[i][j-1]) &\text{if a[i-1]!=b[j-1]}\end{cases}

实现

int dp[MAXN][MAXN]={0};
vector<char> subs;
vector<char> longestCommonSubsequence(string s1, string s2) {
    memset(dp,0,sizeof(dp));
    int m = s1.length(),n = s2.length();
    for(int i=1;i<=m;i++){
    	for(int j=1;j<=n;j++){
    		if(s1[i-1]==s2[j-1])
    			dp[i][j] = dp[i-1][j-1]+1;
    		else dp[i][j] = max(dp[i-1][j],dp[i][j-1]); 
		}
	}
	int k = dp[m][n],i=m,j=n;
	while(k>0){
		if(dp[i][j]==dp[i-1][j])
			i--;
		else if(dp[i][j]==dp[i][j-1])
			j--;
		else {
 			subs.push_back(s1[i-1]);
			i--;j--;k--;
		}
	}
	return subs;
}

来道板子题试试:1143. 最长公共子序列

猜你喜欢

转载自blog.csdn.net/SinclairWang/article/details/102613977
今日推荐