首页 > 试题广场 >

最长公共子序列

[编程题]最长公共子序列
  • 热度指数:6464 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则输出-1。

输入描述:
输出包括两行,第一行代表字符串str1,第二行代表str2。


输出描述:
输出一行,代表他们最长公共子序列。如果公共子序列的长度为空,则输出-1。
示例1

输入

1A2C3D4B56
B1D23CA45B6A

输出

123456

说明

"123456"和“12C4B6”都是最长公共子序列,任意输出一个。  

备注:
时间复杂度,空间复杂度。(n,m分别表示两个字符串长度)

动态规划

import java.util.Scanner;

public class Main {

    public static String process(String str1, String str2) {
        if (str1 == null || str1.length() == 0 || str2 == null || str2.length() == 0) {
            return "";
        }
        char[] char1 = str1.toCharArray();
        char[] char2 = str2.toCharArray();
        int[][] dp = dp(char1, char2);
        int m = str1.length() - 1;
        int n = str2.length() - 1;
        char[] res = new char[dp[m][n]];
        int index = res.length - 1;

        while (index >= 0) {
            if (n > 0 && dp[m][n] == dp[m][n - 1]) {
                n--;
            } else if (m > 0 && dp[m][n] == dp[m - 1][n]) {
                m--;
            } else {
                res[index--] = char1[m];
                m--;
                n--;
            }
        }

        return String.valueOf(res);
    }

    public static int[][] dp(char[] str1, char[] str2) {
        int[][] dp = new int[str1.length][str2.length];
        dp[0][0] = str1[0] == str2[0] ? 1 : 0;

        for (int i = 1; i < str1.length; i++) {
            dp[i][0] = Math.max(dp[i - 1][0], str1[i] == str2[0] ? 1 : 0);
        }
        for (int i = 1; i < str2.length; i++) {
            dp[0][i] = Math.max(dp[0][i - 1], str2[i] == str1[0] ? 1 : 0);
        }
        for (int i = 1; i < str1.length; i++) {
            for (int j = 1; j < str2.length; j++) {
                int max = Math.max(dp[i - 1][j], dp[i][j - 1]);
                if (str1[i] == str2[j]) {
                    max = Math.max(dp[i - 1][j - 1] + 1, max);
                }
                dp[i][j] = max;
            }
        }
        return dp;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.next();
        String str2 = sc.next();
        System.out.println(process(str1, str2));
    }
}
发表于 2019-09-14 20:31:09 回复(0)
原始求最长公共子序列的问题都比较熟悉了,直接用二维表的动态规划求最大长度就行,能够达到题目要求的O(NM)时间和空间复杂度。这个题比较新鲜的地方在于还原这个最长的序列,还是很有魔性的。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] str1 = br.readLine().toCharArray();
        char[] str2 = br.readLine().toCharArray();
        int[][] dp = new int[str1.length + 1][str2.length + 1];
        for(int i = 1; i <= str1.length; i++){
            for(int j = 1; j <= str2.length; j++){
                if(str1[i - 1] == str2[j - 1]){
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }else{
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        // 求完最长公共子序列的长度再把最长公共子序列还原出来
        int m = str1.length;
        int n = str2.length;
        if(dp[m][n] == 0){
            System.out.println(-1);
        }else{
            char[] res = new char[dp[m][n]];
            int index = res.length - 1;
            while(index >= 0){
               if(n > 0 && dp[m][n] == dp[m][n - 1]){
                   n--;        // 不包括str2[n-1]也可以达到这个长度,n就往前指
               }else if(m > 0 && dp[m][n] == dp[m - 1][n]){
                   m--;        // 不包括str1[m-1]也可以达到这个长度,m就往前指
               }else{
                   res[index--] = str1[m - 1];      // 不能不包括str1[m-1]了,追加该字符
                   m--;
                   n--;
               }
            }
            System.out.println(String.valueOf(res));
        }
    }
}

发表于 2021-11-28 19:57:26 回复(0)
#include <bits/stdc++.h>
using namespace std;

int getlenght(const string &str1,const string &str2,vector<vector<int>> &dp){
    dp[0][0]=str1[0]==str2[0] ? 1:0;
    for(int i=1;i<str1.size();i++)
        dp[i][0] = dp[i-1][0]==1 ? 1 : (str1[i]==str2[0]? 1:0);
    for(int j=1;j<str2.size();j++)
        dp[0][j] = dp[0][j-1]==1 ? 1 : (str2[j]==str1[0]? 1:0);

    for(int i=1;i<str1.size();i++){
        for(int j=1;j<str2.size();j++){
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            if(str1[i]==str2[j])
                dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
        }
    }
    return dp[str1.size()-1][str2.size()-1];
}
int main(){
    string str1,str2;
    getline(cin,str1);
    getline(cin,str2);
    vector<vector<int>> dp(str1.size(),vector<int>(str2.size(),0));
    int lenght=getlenght(str1,str2,dp);
    string ans;
    ans.resize(lenght);
    int index = lenght-1,x=str1.size()-1,y=str2.size()-1;
    while(index>=0){
        if(y>=1&&dp[x][y]==dp[x][y-1])
            y--;
        else if(x>=1&&dp[x][y]==dp[x-1][y])
            x--;
        else{
            ans[index--]=str1[x];
            x--;
            y--;
        }
    }
    cout<<ans;
    return 0;
}

发表于 2019-09-18 17:49:00 回复(1)
import java.util.*;

public class Main{
    public static int count = -1;
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        byte[] s1 = in.nextLine().getBytes();
        byte[] s2 = in.nextLine().getBytes();
        for(int i=0;i<s1.length;i++){
            for(int j=0;j<s2.length;j++){
                StringEquals(s1,i,s2,j);
            }
        }
        System.out.println(count);
    }
    public static void StringEquals(byte[] s1, int i, byte[] s2, int j){
        int sum = 0;
        while(i<s1.length&&j<s2.length&&s1[i]==s2[j]){
            sum++;
            i++;
            j++;
        }
        if(sum!=0){
            count = Math.max(count,sum);
        }
    }
}

笑死,在题目题目理解错的基础上(以为是连续子串),想着应该是过不了测试的(准备优化),结果过了,
请问这个测试用例是怎么设计的,这都能过?

发表于 2019-08-29 12:27:00 回复(1)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s1,s2;
    cin>>s1;
    cin>>s2;
    vector<vector<int>>dp(s1.size()+1,vector<int>(s2.size()+1));
    for(int i=0;i<s1.size()+1;i++)
    {
        for(int j=0;j<s2.size()+1;j++)
        {
            if(i==0||j==0)
                dp[i][j]=0;
            else if(s1[i-1]==s2[j-1])
                dp[i][j]=dp[i-1][j-1]+1;
            else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    cout<<dp[s1.size()][s2.size()]<<endl;
    return 0;
}

发表于 2019-08-28 20:52:49 回复(2)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
            String str1 = in.nextLine();
            String str2 = in.nextLine();
            System.out.println(maxSubSequence(str1,str2).length() > 0 ? maxSubSequence(str1,str2):-1);
        }
    }

    public static String maxSubSequence(String str1,String str2) {
        int M = str1.length();
        int N = str2.length();
        //多添加一行一列便于初始化
        int[][] dp = new int[M+1][N+1];//dp[i][j] 表示 str1[0~i-1] 与 str2[0~j-1] 的最长公共子序列的长度
        int maxLen = 0;
        String maxSubSequence = "";
        for(int i = 1;i < M+1;i++){
            for(int j = 1;j < N+1;j++){
                if(str1.charAt(i-1) == str2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else {
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
                }
                if(dp[i][j] > maxLen){
                    maxLen = dp[i][j];
                    maxSubSequence += str1.charAt(i-1);
                }
            }
        }
        return maxSubSequence;
    }
}

编辑于 2019-08-24 10:39:45 回复(1)
// write your code here cpp
#include<iostream>
#include<string>
using namespace std;
class Solution {
public:
	static string fun(string& s1, string& s2) {
		int size1 = s1.size(), size2 = s2.size();
        string res;
		for(int i = 0; i < size1; ++i){
            for(int j = 0; j < size2; ++j){
                if(s1[i] == s2[j]){
                    res += s1[i];
                }
            }
        }
		return res;
	}
};

int main() {
	string s1, s2;
	while (cin >> s1 >> s2) {
		cout << Solution::fun(s1, s2) << endl;
	}
	return 0;
}

编辑于 2020-04-15 11:30:35 回复(1)
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s1, s2, t="";
    cin>>s1>>s2;
    int n=s1.length(), m=s2.length();
    int dp[n+1][m+1];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            if(s1[i]==s2[j]){
                t += s1[i];
                dp[i+1][j+1] = dp[i][j] + 1;
            }else{
                dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
            }
        }
    cout<<t<<endl;
    return 0;
}

发表于 2020-02-22 02:06:58 回复(3)
 public static void main(String args[]) {
        Scanner scan = new Scanner(System.in);
        String str1 = scan.nextLine();
        String str2 =scan.nextLine();
        StringBuilder sb = new StringBuilder();
        int[][] dp = new int[str1.length()+1][str2.length()+1];
        for(int i = 1;i<= str1.length();i++) {
            for(int j = 1;j<=str2.length();j++) {
                if(str1.charAt(i-1) == str2.charAt(j-1)) {
                    sb .append(str1.charAt(i-1));
                    dp[i][j] = 1 + dp[i-1][j-1];
                }else {
                    int v1 = Math.max(dp[i-1][j], dp[i][j-1]);
                    dp[i][j] = v1;
                }
            }
        }
        System.out.println(sb);
    }

发表于 2019-09-02 16:23:30 回复(1)

这是前一半,动态规划求最长公共子序列的长度:力扣-1143-最长公共子序列

扫了一遍他们的题解,大概是逆向遍历一遍去还原字符串

我们来看看怎么根据dp数组把这个串还原

  • 其实是相当于从右下角开始,如果左边/上面有一样数值大小的数字,说明这个位置的字符对公共子序列是没有贡献的,即不是最长公共子序列中的元素,就把它压缩掉
  • 当左边/上面的数字都不一样(小于),说明是有贡献的,就取出这个位置的字符(从任意一个字符串中取都可以,因为是公共的),逆序放到结果数组中
  • 边界条件为0时,上面两个条件判断语句会失效,直接执行最后的else

这里其实两次遍历了dp数组,也就是说,时间复杂度是O(2M*N),空间复杂度是二维数组+res一维数组的长度

#include<iostream>
#include<vector>
using namespace std;

int main() {

    string text1, text2;
    cin >> text1 >> text2;

    int m = text1.size(), n = text2.size();
    // dp[i][0]和dp[0][j]都初始化为0
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));

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

    //for (vector<int> nums : dp) {
    //    for (int num : nums) cout << num << " ";
    //    cout << endl;
    //}

    // 还原字串
    if (!dp[n][m]) cout << -1;
    else {
        vector<char> res(dp[n][m]);
        int index = dp[n][m] - 1;
        while (index >= 0) {
            if (m > 0 && dp[n][m] == dp[n][m - 1]) m--;
            else if (n > 0 && dp[n][m] == dp[n - 1][m]) n--;
            else {
                res[index--] = text2[n - 1];
                n--;
                m--;
            }
        }
        for (char ch : res) cout << ch;
    }
    return 0;
}
编辑于 2022-10-19 23:24:07 回复(0)
str1 = input()
str2 = input()
n, m = len(str1), len(str2)
dp = [[0] * n for _ in range(m)]
dp[0][0] = 0 if str1[0] != str2[0] else 1
for i in range(1, m):
    dp[i][0] = 0 if str1[0] != str2[i] else 1
    dp[i][0] = max(dp[i - 1][0], dp[i][0])
for i in range(1, n):
    dp[0][i] = 0 if str1[i] != str2[0] else 1
    dp[0][i] = max(dp[0][i - 1], dp[0][i])
for i in range(1, m):
    for j in range(1, n):
        if str2[i] == str1[j]:
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + 1)
        else:
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

i, j = m - 1, n - 1
res = []
if dp[-1][-1] == 0:
    print(-1)
    exit()
while j >= 0 and i >= 0:
    if i > 0 and dp[i][j] == dp[i - 1][j]:
        i -= 1
    elif j > 0 and dp[i][j] == dp[i][j - 1]:
        j -= 1
    else:
        res.append(str1[j])
        i -= 1
        j -= 1
print("".join(res[::-1]))

发表于 2022-01-17 13:46:34 回复(0)
#include <iostream>
#include <vector>
#include <string>
using namespace std;

string LCS(string& s1, string& s2, vector<vector<int>>& dp)
{
    int len1 = s1.size();
    int len2 = s2.size();
    int len = dp[len1][len2];
    string ans = "";
    while(len)
    {
        if(len1 >= 1 && dp[len1][len2] == dp[len1 - 1][len2])
            len1--;
        else if(len2 >= 1 && dp[len1][len2] == dp[len1][len2 - 1])
            len2--;
        else
        {
            ans = s1[--len1] + ans;
            len2--;
            len--;
        }
    }
    return ans;
}

int main()
{
    string s1, s2;
    while(cin >> s1 >> s2)
    {
        int len1 = s1.size();
        int len2 = s2.size();
        vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0));
        for(int i = 1; i <= len1; i++)
        {
            for(int j = 1; j <= len2; j++)
            {
                if(s1[i - 1] == s2[j - 1])
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
        string ans = LCS(s1, s2, dp);
        if(ans.size())
            cout << ans << endl;
        else
            cout << -1 << endl;
    }
    return 0;
}

发表于 2021-11-29 22:00:19 回复(0)
import java.io.*;

public class Main{
    public static void main(String[] args)throws Exception{
        try(BufferedReader bf = new BufferedReader(new InputStreamReader(System.in))){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str1 = br.readLine();
        String str2 = br.readLine();
        String result = lcse(str1, str2);
         System.out.println(result.equals("") ? -1 : result);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
     public static int[][] getdp(char[] str1,char[] str2){
        int[][] dp=new int[str1.length][str2.length];
        dp[0][0]=str1[0]==str2[0]?1:0;
        for(int i=1;i<str1.length;i++){
            dp[i][0]=Math.max(dp[i-1][0],str1[i]==str2[0]?1:0);
        }
        for(int j=1;j<str2.length;j++){
            dp[0][j]=Math.max(dp[0][j-1],str1[0]==str2[j]?1:0);
        }
        for(int i=1;i<str1.length;i++){
            for(int j=1;j<str2.length;j++){
                dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                if(str1[i]==str2[j]){
                    dp[i][j]=Math.max(dp[i][j],dp[i-1][j-1]+1);
                }
            }
        }
        return dp;
    }
    public static String lcse(String str1,String str2){
        if(str1==null||str2==null||str1.equals("")||str2.equals("")){
            return "";
        }
        char[] chs1=str1.toCharArray();
        char[] chs2=str2.toCharArray();
        int[][] dp=getdp(chs1,chs2);
        int m=chs1.length-1;
        int n=chs2.length-1;
        char[] res=new char[dp[m][n]];
        int index=res.length-1;
        while (index>=0){
            if(n>0&&dp[m][n]==dp[m][n-1]){
                n--;
            }else if(m>0&&dp[m][n]==dp[m-1][n]){
                m--;
            }else{
                res[index--]=chs1[m];
                m--;
                n--;
            }
        }
        return String.valueOf(res);
    }
   
}


发表于 2021-03-19 08:57:03 回复(0)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 5000 + 10;
char str1[MAX];
char str2[MAX];

//ij的0下标不用,作为哨兵,表示当前含头子串为空串
int dp[MAX][MAX];//dp[i][j]表示str1[1..i]和str2[1..j](含头子串)的最长公共子序列长度
int b[MAX][MAX];//0,1,2分别表示dp[i][j]是dp[i-1][j-1],dp[i-1][j],dp[i][j-1]三种情况计算而来的

int Func(int n,int m){
    //初始化空串的最长公共子序列长度都为0
    for (int i = 0; i <= n;++i)
        dp[i][0] = 0;
    for (int j = 0; j <= m; ++j)
        dp[0][j] = 0;
    //end
    //递推计算dp与b
    for (int i = 1; i <= n;++i){
        for (int j = 1; j <= m;++j){
            int answer;
            int tb;
            if(str1[i]==str2[j]){
                answer = dp[i - 1][j - 1] + 1;
                tb = 0;//表示第一种情况
            }
            else{
                if (dp[i - 1][j] >= dp[i][j - 1]){
                    answer = dp[i - 1][j];
                    tb = 1;
                }
                else
                {
                    answer = dp[i][j - 1];
                    tb = 2;
                }
            }
            dp[i][j] = answer;
            b[i][j] = tb;
        }
    }
    return dp[n][m];
}

string compute(int n,int m){//给出具体最长公共子序列
    string answer = "";
    int i = n, j = m;
    while(i>=1&&j>=1){
        if (b[i][j] == 0)
        {
            answer.push_back(str1[i]);
            i--;
            j--;
        }
        else if (b[i][j] == 1)
            i--;
        else
            j--;
    }
    reverse(answer.begin(), answer.end());
    if(answer=="")
        answer="-1";
    return answer;
}
int main(){
    int n, m;
    scanf("%s %s", str1 + 1, str2 + 1);//加1是保证0号下标不存元素,从下标1开始
    n = strlen(str1 + 1);//要+1,不然str[0]可能为\0,长度就为0了
    m = strlen(str2 + 1);
    Func(n, m);
    cout << compute(n, m) << endl;
    return 0;
}
发表于 2021-02-23 10:52:40 回复(0)
#include<iostream>
using namespace std;
const int N = 5000+10;
int end_[N][N];

string lcs(string& a, string &b) {
    int n = a.size(),m = b.size();
    int len =end_[n][m];
    string res(len,'0');
     
    while(len) {
        if(n>=1 && end_[n][m] == end_[n-1][m]) --n;
        else if(m>=1 && end_[n][m] == end_[n][m-1]) --m;
        else {
            res[--len] = a[--n];
            --m;
        }
    }
    return res;
    
}


int main() {
    string a,b;
    cin>>a>>b;
    
    
    for(int i=1;i<=a.size();++i) {
        for(int j=1;j<=b.size();++j) {
           
            end_[i][j] = max(end_[i][j-1],end_[i-1][j]);
            if(a[i-1]==b[j-1]) end_[i][j] = max(end_[i][j] ,end_[i-1][j-1]+1);
             
        }
    }
    cout << lcs(a,b) <<endl;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    return 0;
        
        
        
}
答案卡在 80% ,但是我感觉我的没有错
发表于 2021-01-31 00:24:08 回复(1)
这个题有bug,错误的代码可以通过。
写个 1 + 1 = 2 都可以过。
或者写个1,也可以过。
只要代码不空着,都能过。快过吧牛客er们。
发表于 2020-07-18 17:36:23 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        char[] str1 = bf.readLine().toCharArray();
        char[] str2 = bf.readLine().toCharArray();
        int[][] dp = new int[str1.length+1][str2.length+1];
        int[][] dr = new int[str1.length][str2.length];
        int n = str1.length;
        int m = str2.length;
        for (int i=1;i<=n;i++){
            for (int j=1;j<=m;j++){
                if (str1[i-1]==str2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                    dr[i-1][j-1] = 1;
                }else {
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                    dr[i-1][j-1] = dp[i-1][j]>=dp[i][j-1]?2:3;
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i=n-1, j=m-1;i>=0&&j>=0;){
            if (dr[i][j]==1){
                sb.append(Character.valueOf(str1[i]));
                i--;
                j--;
            }else if (dr[i][j]==2){
                i--;
            }else if (dr[i][j]==3){
                j--;
            }
        }
        sb = sb.reverse();
        System.out.print(sb);
    }
}

发表于 2020-07-01 08:57:01 回复(0)

C++ 思路清晰的代码

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 5007;

int f[N][N];
int n, m;
string a, b;

void getString(int i, int j, int len) { // len表示最大公共子序列的长度
    string s;
    while (i >= 1 && j >= 1) { // 倒序还原
        if (a[i - 1] == b[j - 1]) {
            s += a[i - 1];
            i--, j--;
        } else {
            if (f[i - 1][j] >= f[i][j - 1]) { // 说明是有f[i-1][j]转移过来的
                i --;
            } else j --;
        }
    }

    reverse(s.begin(), s.end());
    cout << s << endl;
}

int main() {
    cin >> a >> b;
    n = a.size(), m = b.size();
    // "f[i][j]"表示所有A[1,...,i]与B[1,...,j]的公共子序列的集合,属性:最大值
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i - 1] == b[j - 1]) { 
                s
                f[i][j] = f[i - 1][j - 1] + 1;
            } else {
                f[i][j] = max(f[i - 1][j], f[i][j - 1]); // 集合"f(i-1,j)"和"f(i,j-1)"有相交部分,但求最值可重复
            }
        }
    }

    int len = f[n][m]; // 最长公共子序列的长度
    if (len == 0) cout << -1 << endl;
    else getString(n, m, f[n][m]);

    return 0;
}
发表于 2020-05-31 21:00:04 回复(0)
这个题有bug,直接运行下面的代码就能通过
public class Main{
    public static void main(String[] args){
      
    }
}


编辑于 2020-05-21 22:14:43 回复(0)
import java.util.Scanner;

public class Main{
    public int longestCommenSubSequence(String s1,String s2){
        int len1 = s1.length(),len2 = s2.length();
        int[][] dp = new int[len1+1][len2+1];
        for(int i=1;i<=len1;++i){
            for(int j=1;j<=len2;++j){
                if(s1.charAt(i-1)==s2.charAt(j-1)) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
        return dp[len1][len2];
    }
    public static void main(String[] args){
        Main c = new Main();
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        int res = c.longestCommenSubSequence(s1,s2);
        System.out.println(res);
    }
}

发表于 2020-04-11 14:20:49 回复(1)

问题信息

上传者:小小
难度:
22条回答 7934浏览

热门推荐

通过挑战的用户

查看代码