Dynamic Programming: Longest Common Subsequence

Dynamic Programming: Longest Common Subsequence


foreword

Given two strings text1 and text2, return the length of the longest common subsequence of these two strings. Returns 0 if no common subsequence exists.

A subsequence of a string refers to such a new string: it is a new string formed by deleting some characters (or not deleting any characters) from the original string without changing the relative order of the characters.

For example, "ace" is a subsequence of "abcde", but "aec" is not a subsequence of "abcde".
A common subsequence of two strings is a subsequence that both strings have in common.
Example 1:
Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: The longest common subsequence is "ace", and its length is 3.
Example 2:
Input: text1 = "abc", text2 = "abc"
Output: 3
Explanation: The longest common subsequence is "abc", and its length is 3.
Example 3:
Input: text1 = "abc", text2 = "def"
Output: 0
Explanation: Two strings have no common subsequence, return 0.

Hint:
1 <= text1.length, text2.length <= 1000
text1 and text2 consist of lowercase English characters only.


1. Dynamic programming

The violent method can still solve this problem, but the problem is that the time complexity will be overtime, so it will not be described here, only the algorithm of dynamic programming will be introduced

The core idea of ​​dynamic programming is
insert image description here
to find the length of the common subsequence:

	int longestCommonSubsequence(string text1, string text2) {
    
    
	int size1 = text1.size();
	int size2 = text2.size();
	vector<vector<int>> dp(size1+1, vector<int>(size2+1, 0));
	for(int i=1;i<=size1;i++) {
    
    
		for(int j=1;j<=size2;j++) {
    
    
			if(text1[i-1] == text2[j-1]) {
    
    
			dp[i][j] = dp[i-1][j-1] + 1;
			} else {
    
    
			dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
			}
		}
	}
	return dp[size1][size2];
}

Print the contents of the common subsequence:

void lcsPrint(vector<vector<int>> B, string X, int i, int j) {
    
    
	if (i == 0 || j == 0) {
    
    
	return;
	}
	if (B[i][j] == 2) {
    
    
		lcsPrint(B, X, i - 1, j - 1);
		cout<<X[i-1]<<endl;
	}
	else if (B[i][j] == 1) {
    
    
		lcsPrint(B, X, i - 1, j);
	}
	else {
    
    
		lcsPrint(B, X, i, j - 1);
	}
}

int main() {
    
    
string X = "ADBCDACBA";
string Y = "ABCADBACB";
int i = 0;
int j = 0;
int size1 = X.size();
int size2 = Y.size();
vector<vector<int>> dp(size1+1, vector<int>(size2+1, 0));
vector<vector<int>> B(size1+1, vector<int>(size2+1, -1));
for(i=1;i<=size1;i++) {
    
    
	for(j=1;j<=size2;j++) {
    
    
		if(X[i-1] == Y[j-1]) {
    
    
		dp[i][j] = dp[i-1][j-1] + 1;
		B[i][j] = 2;
		} else if(dp[i-1][j] >= dp[i][j-1]){
    
    
			dp[i][j] = dp[i-1][j];
			B[i][j] = 1;
		} else {
    
    
			B[i][j] = 0;
			dp[i][j] = dp[i][j-1];
		}
	}
}
lcsPrint(B, X, size1, size2);
cout<<endl;
cout<<dp[size1][size2];
return 0;

For more content, please refer to:
Dynamic Programming Longest Common Subsequence Process Diagram
Longest Common Subsequence

Guess you like

Origin blog.csdn.net/qq_46119575/article/details/131230716
Recommended