Longest palindromic sequence LCS, the longest increasing subsequence LIS and interrelated

Longest common subsequence LCS

Lintcode 77. longest common subsequence
LCS problem is the sum of two strings of the longest common subsequence
\ [dp [i] [j ] = \ left \ {\ begin {matrix} & max (dp [i-1] [j], dp [i] [j-1]), s [i]! = s [j] \\ & dp [i-1] [j-1] + 1, s [i] == s [ j] \ end {matrix} \
right. \] many problems can be modified to solve the problem as LCS

class Solution {
public:
    /**
     * @param A: A string
     * @param B: A string
     * @return: The length of longest common subsequence of A and B
     */
    int longestCommonSubsequence(string &A, string &B) {
        // write your code here
        int n = A.size();
        int m = B.size();
        std::vector<vector<int>> dp(m+1, vector<int>(n+1, 0)) ;
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
               
                if(A[i-1] == B[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[m][n];
    }
};

Because dp [i] [j] only uses the data i-1 and i-layer, can be used to scroll the array to the compression space, so that the degree of complexity of the space \ (O (min (m, n)) \)

class Solution {
public:
    /**
     * @param A: A string
     * @param B: A string
     * @return: The length of longest common subsequence of A and B
     */
    int longestCommonSubsequence(string &A, string &B) {
        // write your code here
        int n = A.size();
        int m = B.size();
        std::vector<vector<int>> dp(2, vector<int>(n+1, 0)) ;
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
               
                if(A[i-1] == B[j-1]) dp[i%2][j] = dp[(i-1)%2][j-1] + 1;
                else dp[i%2][j] = max(dp[(i-1)%2][j], dp[i%2][j-1]);
              
            }
        }
        
        return dp[m%2][n];
    }
};

LIS longest increasing subsequence

300. Longest Increasing Subsequence

Dynamic Programming

Can be assumed dp [i] is to nums [i] at the end of the LIS length, dp [i] = max (dp [j] + 1) (j <i and nums [j] <nums [i ]), the time complexity degree \ (O (^ n-2) \) , the time complexity is \ (O (n) \)

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n, 1);
        int MAX = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < i; j++){
                if(nums[i] > nums[j]) dp[i] = max(dp[j] + 1, dp[i]);
            }
            MAX = max(MAX, dp[i]);
        }
        
        return MAX;
    }
};

Greedy + half

First we set an auxiliary array v, where v [I] indicates the length of the LIS end value i-1, first scanning the original array, when the process to nums [i] and data v in the comparison, binary search final ratio nums [i] small value, and replace, if not, then added to the end, the final length is the length of the original array v LIS, the time complexity \ (nlgn \)

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> v;
        
        for(int i = 0; i < n; ++i){
            auto loc = lower_bound(v.begin(), v.end(), nums[i]);
            if(loc == v.end()) v.push_back(nums[i]);
            else *loc = nums[i];
        }
        
        return v.size();
    }
};

If only the required length and allow the LIS to change the original array, spatial complexity may be reduced to \ (O (1) \)

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        auto p = nums.begin();
        auto q = nums.begin();
        
        for(int i = 0; i < n; i++){
            auto r = lower_bound(p, q, nums[i]);
            if(r == q){ ++q; }
            *r = nums[i];
        }
        
        return q - p;
    }
};

LIS and the LCS interconversion

LIS LCS problem can be transformed into the problem, such as the input array [5,1,4,2,3], longest increasing sequence is [2,3], may first obtain a new original array sorted array [1 , 2,3,4,5], then the original array with the new array as inputs to solve the LCS, the time complexity is \ (O (n ^ 2) \ ) , the spatial complexity degree \ (O (n ^ 2) \ )

LIS LCS problem can become problems, assuming that the input array is an array of numbers such as A = [1,7,5,4,8,3,9], B = [1,4,3,5,6,2,8 , 9], and the two sequences a, B each element varies (e.g., 1-n is arranged), if the LCS solving the longest common subsequence length, complexity \ (O (n ^ 2 ) \) , A, B each element in the two sequences is different, so we can re-encode A A = [1,2,3,4,5,6,7] (coding not repeated), B can be encoded as B = [1,4,6,3,0,0,5,7] (0 indicates absence, may be directly deleted), and then re-encoded after the request a, LIS length B, the time complexity is \ (O (nlgn) \)

LCS longest palindromic sequence variants and LPS

Longest palindromic sequence may be used to request LCS S idea obtained by inverting the first S S ', then find LCS (S, S')
leetcode 516. Longest palindromic Subsequence

class Solution {
public:
    int lcs(string &A, string &B) {
        int n = A.size();
        int m = B.size();
        std::vector<vector<int>> dp(m+1, vector<int>(n+1, 0)) ;
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
               
                if(A[i-1] == B[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[m][n];
    }
    int longestPalindromeSubseq(string s) {
        string t(s.rbegin(), s.rend()); 
        return lcs(s, t);
    }
};

Variants: S anywhere in seeking to insert or delete such that S is a minimum number of characters palindromic sequence
Solution: first find the longest palindromic sequence, then the length of the original length -LPS

Not for the length of the original sequence seek

reference

Guess you like

Origin www.cnblogs.com/qbits/p/11230679.html