8 minutes to learn the longest common subsequence (with C + + source code, the one that runs directly)

Posted by dragon_sa on Sat, 05 Mar 2022 21:52:52 +0100

Algorithm is really wonderful. It's easy to be addicted after learning. Of course, it's said on a simple premise. If I encounter that kind of problem, I also have a headache.

Today's plot is still the form of dialogue between teachers and students. In this way, I think it is more gradual and less abrupt. What do you think?

Now, students, let's look at the two questions on the teacher's courseware:

Question 1: give two integer arrays A and B, and return the length of the common and longest sub array in the two arrays.

Example:

Input: A: [1,2,3,2,1] B: [3,2,1,4,7] output: 3 explanation: the common subarray with the longest length is [3,2,1].

Question 2: given two strings text1 and text2, return the length of the longest common subsequence of the two strings.

For example, "ace" is a subsequence of "abcde", but "aec" is not a subsequence of "abcde". The "common subsequence" of two strings is the subsequence shared by the two strings.

If the two strings have no common subsequence, 0 is returned.

Example 1:

Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: the longest common subsequence is "ace", and its length is 3.

The above are two questions. I'll give you five minutes. Please observe the similarities and differences between the two questions.

Five minutes, Komatsu, you answer the difference.

"I think the first question emphasizes that the counting will continue only if the continuous subsequences are the same. If the previous series of sequences are the same, the counting will start from 0 until the next element is different, but it is necessary to redefine a variable to receive the length of the last largest subsequence; and the second question is whether continuous or not, as long as the alphabetical order in text2 is the same as that in text1 If the same alphabetical order is consistent, you can count continuously, so this second question does not emphasize continuity. "

What do you say, Xiao Song?

Very good. Who will answer the common ground?

This time Xiao Gang volunteered to raise his hand. Let me say it, teacher. Let me say it. I'm suffocating

OK, let Xiao Gang tell you.

"I can solve this problem. I summarized in the last program that as long as it is to find the longest * * * subsequence, it must be traversed. Moreover, these two problems are given to two groups respectively, and both of them find the number of the same elements in the second group in the first group, but the first one emphasizes continuity and the second one does not emphasize continuity."

Ah? (the teacher looks surprised) this little guy just came here, isn't it changing too fast

Hehe, the main thing is to teach well

OK, that's good. Who can say what the code of these two topics is? It needs to be able to run directly

OK, let Xiao Li say the first question and Xiao Lu do the second.

#include <iostream>
#include <vector>
using namespace std;
int findLength(vector<int>& nums1,vector<int>& nums2)
{
    vector<vector<int>>dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
    int result=0;
    for(int i=1;i<=nums1.size();++i)
    {
        for(int j=1;j<=nums2.size();j++)
        {
            if(nums1[i-1]==nums2[j-1])
            {
                dp[i][j]=dp[i-1][j-1]+1;
                if(dp[i][j]>result)
                result=dp[i][j];
            }
        }
    }
    return result;
}
int main()
{
    vector<int> num1={1,2,3,2,1};
    vector<int> num2={3,2,1,4,7};
    int ret=findLength(num1,num2);
    cout<<"ret="<<ret<<endl;
    return 0;
}

Teacher, let me explain that dp[i][j] is obtained by adding 1 to the value of the same element in their previous group.

I have finished this problem, and the result of my calculation is 3

Other students have worked out the first question. How much is it? 3 (with one voice), good

#include <iostream>
#include <vector>
using namespace std;
int findLength(string& text1,string& text2)
{
    vector<vector<int>>dp(text1.size()+1,vector<int>(text2.size()+1,0));
    int result=0;
    for(int i=1;i<=text1.size();++i)
    {
        for(int j=1;j<=text2.size();j++)
        {
            if(text1[i-1]==text2[j-1])//If equal
            {
                dp[i][j]=dp[i-1][j-1]+1;
                
            }
            else//If not equal
            {
                dp[i][j]=max(dp[i][j-1],dp[i-1][j]);    
            }
                if(dp[i][j]>result)
                result=dp[i][j];
        }
    }
    return result;
}
int main()
{
    string text1="abcde";
    string text2="ace";
    int ret=findLength(text1,text2);
    cout<<"ret="<<ret<<endl;
    return 0;
}

Teacher, let me explain:

When text1 [I-1]= When text2 [J-1], maximize the value of the previous element of text1 and text2 respectively.

The result of my run this time is also 3.

Are there any differences among other students? All the same (with one voice) good!

Topics: C++ Algorithm leetcode Dynamic Programming