[Interview Algorithm - Dynamic Programming 20] Longest Common Subsequence && Disjoint Lines

1143. Longest common subsequence

Link: 1143. Longest common subsequence

Given two strings text1 and text2, return the length of the longest common subsequence of these two strings. If there is no common subsequence, return 0.

A subsequence of a string refers to a new string that is composed of the original string by deleting some characters (or not deleting any characters) without changing the relative order of the characters.

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 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: The two strings have no common subsequence, return 0.

1. State representation *
state representation:
For dynamic programming of two arrays, our experience in defining state representation is:

i. Select the interval of the first array [0, i] and the interval of the second array [0, j] as the research objects; ii
. Combined with the requirements of the topic, define the status representation.
In this question, we express the state according to the definition as:
dp[i][j] means: among all the subsequences in the [0, i] interval of s1 and the [0, j] interval of s2, the most
The length of the long common subsequence

2. State transition equation
The experience in analyzing the state transition equation is to discuss it based on the situation of the "last position".
For dp[i][j], we can discuss according to the characters of s1[i] and s2[j]:

  1. . Two characters are the same, s1[i] = s2[j]: Then the longest common subsequence is found in the interval of [0, i - 1] of s1 and [0, j - 1] of s2 , and then add s1[i]. thereforedp[i][j] = dp[i - 1][j - 1] + 1 ;
  2. ii. The two characters are not the same, s1[i] != s2[j]: Then the longest common subsequence must not end with s1[i] and s2[j] at the same time. Then when we find the longest common subsequence, we have the following three strategies:
    Find within the interval [0, i - 1] of s1 and [0, j] of s2: at this time, the maximum length is dp[i - 1][j];
    Go to [0, i] of s1 and [0, j - 1] of s2 to find in the interval: the maximum length at this time is dp[i] [j - 1]; Go to [0 of
    s1 , i - 1] and find within the [0, j - 1] interval of s2: the maximum length at this time is dp[i - 1][j - 1]

We just want the maximum value of the three. But if we look closely, we will find that the third one is included in the first and second situations, but what we are looking for is the maximum value, which does not affect the final result. Therefore, only the maximum value in the first two cases is required.
To sum up, the state transfer process is:

if(s1[i] == s2[j]) dp[i][j] = dp[i - 1][j - 1] + 1 ;
if(s1[i] != s2[j]) dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

3. Initialization
a. "Empty string" is of research significance, so we add one more row and one column to the size of the original dp table to represent the empty string.
b. After introducing the empty string, it greatly facilitates our initialization.
c. But you should also pay attention to the "mapping relationship of subscripts" and the values ​​inside to "ensure that subsequent filling in the form is correct."
When s1 is empty, it has no length, and the same is true for s2. Therefore, the values ​​in the first row and column are initialized to 0 to ensure that subsequent filling in the form is correct.

4. The order of filling in the form
is based on the "State Transition Equation": fill in each line from top to bottom, and each line from left to right.

5. Return value
Return dp[m][n]

Code:

 int longestCommonSubsequence(string text1, string text2) {
    
    
        int n=text1.size();
        int m=text2.size();

        vector<vector<int>> dp(n+1,vector<int>(m+1));
        for(int i=1;i<=n;i++)
        {
    
    
            for(int j=1;j<=m;j++)
            {
    
    
                if(text1[i-1]==text2[j-1])
                {
    
    
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else
                {
    
    
                    dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
                }
            }
        }
        return dp[n][m];
    }

Insert image description here

1035. Disjoint lines

Link: 1035. Disjoint lines
Write the integers in nums1 and nums2 in the given order on two independent horizontal lines.

Now, you can draw some straight lines connecting the two numbers nums1[i] and nums2[j]. These straight lines need to satisfy at the same time:

nums1[i] == nums2[j]
and the straight line drawn does not intersect any other connected lines (non-horizontal lines).
Note that lines cannot intersect even at their endpoints: each number can belong to only one line.

Draws lines this way and returns the maximum number of connections that can be drawn.
Insert image description here
Input: nums1 = [1,4,2], nums2 = [1,2,4]
Output: 2
Explanation: Two lines that do not cross can be drawn, as shown in the figure above.
But a third disjoint straight line cannot be drawn because the straight line from nums1[1]=4 to nums2[2]=4 will intersect the straight line from nums1[2]=2 to nums2[1]=2.
Example 2:

Input: nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
Output: 3
Example 3:

Input: nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
Output: 2

Solution idea:
Let’s analyze the problem carefully and find two non-intersecting lines, that is, we are looking for the longest common subsequence in the two arrays .

The detailed solution has already been written in the previous question, so I won’t repeat it again.

code

  int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
    
    

 int n=nums1.size();
        int m=nums2.size();

        vector<vector<int>> dp(n+1,vector<int>(m+1));
        for(int i=1;i<=n;i++)
        {
    
    
            for(int j=1;j<=m;j++)
            {
    
    
                if(nums1[i-1]==nums2[j-1])
                {
    
    
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else
                {
    
    
                    dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
                }
            }
        }
        return dp[n][m];
    }

Insert image description here

Guess you like

Origin blog.csdn.net/m0_64579278/article/details/133325236