最长公共子序列问题

问题描述

给定两个数组,求出两个数组中公共的最长子序列以及子序列的长度

算法思路

假设有两个数组,array1={x1,x2,x3,x4…xm},array2={y1,y2,y3,y4,…yn},要找出他们的最长公共子序列,可以递归的进行定义,若是xm==yn,则找出array1[m-1]和array2[n-1]的最长公共子序列,然后加上xm即可;若是xm!=yn,找出array1[m-1]和array2[n]的的最长公共子序列和array1[m]和array2[n-1]的的最长公共子序列,取其中较大者即可。
令array[i][j] 记录序列xi和yj的最长公共子序列的长度,建立如下关系:

array[i][j]=0 (i==0||j==0)
array[i][j]=array[i-1][j-1]+1 (xi==yj)
array[i][j]=max{array[i-1][j],array[i][j-1]} (xi!=yj)

同时令position数组保存子序列的值,position数组满足如下关系

position[i][j]=1; (array1[i]==array2[j])
position[i][j]=2; (array1[i-1][j]>=array1[i][j-1])
position[i][j]=3;(array1[i-1][j]

public static Map<String,Object> getCommonSequenceLength(int[] array1,int[] array2){
        int n=array1.length;
        int m=array2.length;
        int[][] array=new int[n][m];
        int[][] position=new int[n][m];
        for(int i=0;i<n;i++){
            array[i][0]=0;
        }
        for(int j=0;j<m;j++){
            array[0][j]=0;
        }
        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                if(array1[i]==array2[j]){
                    array[i][j]=array[i-1][j-1]+1;
                    position[i][j]=1;
                }else{
                    if(array[i-1][j]>=array[i][j-1]){
                        array[i][j]=array[i][j-1];
                        position[i][j]=2;
                    }else{
                        array[i][j]=array[i-1][j];
                        position[i][j]=3;
                    }
                }
            }
        }
        int max=array[0][0];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(max<array[i][j]){
                    max=array[i][j];
                }
            }
        }
        Map<String, Object> map=new HashMap<String, Object>();
        map.put("length", max);
        map.put("position", position);
        return map;
    }

构造子序列的值,当两者相等时,就可以输出即position[i][j]==1

public static void getCommonSequence(int i,int j,int[] array,int [][] position){
        if(i==0||j==0){
            return;
        }
        if(position[i][j]==1){
            getCommonSequence(i-1, j-1, array, position);
            System.out.print(array[i]+" ");
        }else if(position[i][j]==2){
            getCommonSequence(i-1, j, array, position);
        }else{
            getCommonSequence(i, j-1, array, position);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值