【leetcode】最长公共子序列

最长公共子序列可延生出两个题目

输入:
[0,1,1,1,1] [1,0,1,0,1]

输出:
最长连续公共子序列为2,[0,1]
最长公共子序列(可不连续)为3,[1,1,1]

最长连续公共子序列

leetcode:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/
d p [ i ] [ j ] dp[i][j] dp[i][j] A 数 组 前 i 个 和 B 数 组 前 j 个 中 的 满 足 要 求 子 序 列 的 最 长 值 A 数组前i个和B数组前j个中的满足要求子序列的最长值 AiBj
状 态 方 程 : 状态方程: :
d p [ i ] [ j ] = { d [ i − 1 ] [ j − 1 ] + 1 if( A [ i ] = = B [ j ] ) 0 else dp[i][j]= \begin{cases} d[i-1][j-1] + 1 & \text {if($A[i] == B[j]) $} \\ 0 & \text {else} \end{cases} dp[i][j]={d[i1][j1]+10if(A[i]==B[j])else
因 为 要 求 连 续 , 只 要 间 断 , 就 是 0 因为要求连续,只要间断,就是0 0

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size();        
        int m = B.size();
        int dp[n+2][m+2];
        int maxn = 0;
        memset(dp,0,sizeof(dp));         
        for(int i = 1 ;i <= n;i++){
            for(int j = 1;j <= m;j++){
                if(A[i-1] == B[j-1])
                    dp[i][j] = dp[i-1][j-1] + 1;
	            maxn = max(dp[i][j],maxn);	            
            }                            
        }
        return maxn;
    }
};

最长公共子序列(可以不连续):类似于最长递增子序列

d p [ i ] [ j ] dp[i][j] dp[i][j] A 数 组 前 i 个 和 B 数 组 前 j 个 中 的 满 足 要 求 子 序 列 的 最 长 值 A 数组前i个和B数组前j个中的满足要求子序列的最长值 AiBj
状 态 方 程 : 状态方程: :
d p [ i ] [ j ] = { d [ i − 1 ] [ j − 1 ] + 1 if( A [ i ] = = B [ j ] ) m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) else dp[i][j]= \begin{cases} d[i-1][j-1] + 1 & \text {if($A[i] == B[j]) $} \\ max(dp[i-1][j],dp[i][j-1]) & \text {else} \end{cases} dp[i][j]={d[i1][j1]+1max(dp[i1][j],dp[i][j1])if(A[i]==B[j])else
如 果 间 断 , 那 么 当 前 的 最 大 值 就 是 前 面 状 态 的 值 中 的 最 大 值 如果间断,那么当前的最大值就是前面状态的值中的最大值

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size();        
        int m = B.size();
        int dp[n+2][m+2];
        memset(dp,0,sizeof(dp));         
        for(int i = 1 ;i <= n;i++){
            for(int j = 1;j <= m;j++){
                if(A[i-1] != B[j-1]){
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1]);  
                }
                else
                    dp[i][j] = dp[i-1][j-1] + 1;                    
            }                            
        }
        return dp[n][m];
    }
};

区别

也正是这个原因,使得连续求最大需要遍历求最大,不连续求最大则是dp[n][m] 就是最大值。

你可能感兴趣的:(LeetCode)