最长公共子序列问题

题目描述

对于两个字符串,请设计一个高效算法,求他们的最长公共子序列的长度,这里的最长公共子序列定义为有两个序列U1,U2,U3...Un和V1,V2,V3...Vn,其中Ui&ltUi+1,Vi&ltVi+1。且A[Ui] == B[Vi]。

给定两个字符串AB,同时给定两个串的长度nm,请返回最长公共子序列的长度。保证两串长度均小于等于300。

测试样例:

"1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6
import java.util.*;

public class LCS {
    /*
     *  i=0||j=0,dp[i][j]=0
     *  A[i-1]=B[j-1],dp[i][j]=dp[i-1][j-1]+1
     *  A[i-1]!=B[j-1],dp[i][j]=Max(dp[i-1][j],dp[i][j-1])
     */
    public int findLCS(String A, int n, String B, int m) {
        if(A==null||B==null||n==0||m==0){
            return 0;
        }
        int[][] dp=new int[n+1][m+1];
        for(int i=0;i<=n;i++){
            dp[i][0]=0;
        }
        for(int j=0;j<=m;j++){
            dp[0][j]=0;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(A.charAt(i-1)==B.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[n][m];
    }
}

题目描述

给定两个字符串str1和str2,输出连个字符串的最长公共子序列。如过最长公共子序列为空,则输出-1。

输入描述:

输出包括两行,第一行代表字符串str1,第二行代表str2。\left( 1\leq length(str1),length(str2) \leq 5000\right)(1≤length(str1),length(str2)≤5000)

输出描述:

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

示例1

输入

复制

1A2C3D4B56
B1D23CA45B6A

输出

复制

123456

说明

"123456"和“12C4B6”都是最长公共子序列,任意输出一个。
import java.util.Scanner;
import java.lang.Math;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
        int m=str1.length();
        int n=str2.length();
        System.out.println(getMaxStr(str1,m,str2,n));
    }
    public static String getMaxStr(String str1,int m,String str2,int n){
        if(str1==null||str2==null||m==0||n==0){
            return "-1";
        }
        int[][] dp=new int[m+1][n+1];
        for(int i=0;i<=m;i++){
            dp[i][0]=0;
        }
        for(int j=0;j<=n;j++){
            dp[0][j]=0;
        }
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;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]);
                }
            }
        }
        int i=m;
        int j=n;
        int index=0;
        StringBuilder sb=new StringBuilder();
        while(index<dp[m][n]){
            if(str1.charAt(i-1)==str2.charAt(j-1)){
                sb.append(str1.charAt(i-1));
                i--;
                j--;
                index++;
            }else{
                if(dp[i-1][j]>dp[i][j-1]){
                    i--;
                }else{
                    j--;
                }
            }
        }
        if(sb.length()==0){
            return "-1";
        }else{
            return sb.reverse().toString();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值