动态规划—LCS最长公共子序列

作者: 宛丘之上兮 | 来源:发表于2019-11-08 13:54 被阅读0次

Main.java

package com.company.zzh;

public class Main {

    public static void main(String[] args) {
        System.out.println("非连续最长子序列" + findLCS("AB1C2", "aAB34CD", false));
        System.out.println("连续最长子序列" + findLCS("AB1C2", "aAB34CD", true));
    }

    public static int findLCS(String A, String B, boolean close) {//clsoe要求子序列必须连续
        int aL = A.length(), bL = B.length();
        //创建dp数组
        int[][] dp = new int[aL][bL];
        char[] a = A.toCharArray(), b = B.toCharArray();
        int i, j, closeMax = 0;
        for (i = 0; i < aL; i++) {
            for (j = 0; j < bL; j++) {
                if (a[i] == b[j]) {
                    //1如果不在边缘,当前值=左上角的值+1;如果在边缘,当前值就是1
                    dp[i][j] = i == 0 || j == 0 ? 1 : dp[i - 1][j - 1] + 1;
                    if (dp[i][j] > closeMax) {//要求子序列必须连续
                        closeMax = dp[i][j];
                    }
                } else {
                    //如果不要求子序列连续,那么当前值需要取 左边 和 上边 的较大者
                    if (!close) {
                        dp[i][j] = Math.max(dp[Math.max(i - 1, 0)][j], dp[i][Math.max(j - 1, 0)]);
                    }
                    //如果要求子序列连续,那么当前值就是数组初始化时候的默认的0,不需要再做处理了
                }
            }
        }

        Util.printAray(dp, A, B);//打印二维数组
        return close ? closeMax : dp[aL - 1][bL - 1];
    }
}

Util.java,这个是工具类,用来打印二维数组,看起来直观一些:

package com.company.zzh;

public class Util {
    public static <T> void printAray(int[][] arr, String A, String B) {
        System.out.print("   ");
        for (int i = 0; i < B.length(); i++) {
            boolean end = i == B.length() - 1;
            System.out.print(B.charAt(i) + (end ? "" : ", "));
        }
        System.out.println();
        int row = arr.length;
        int col = arr[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (j == 0) {
                    System.out.print(A.charAt(i) + "  ");
                }
                boolean end = j == col - 1;
                System.out.print(arr[i][j] + (end ? "" : ", "));
            }
            System.out.println();
        }
    }
}

解释下Main.java代码中的clsoe变量,一般这个值是false表示子序列可以是非连续的。如果为true表示要求子序列必须是连续的,这样的需求其实比为false更好做。

输出的结果:

   a, A, B, 3, 4, C, D
A  0, 1, 1, 1, 1, 1, 1
B  0, 1, 2, 2, 2, 2, 2
1  0, 1, 2, 2, 2, 2, 2
C  0, 1, 2, 2, 2, 3, 3
2  0, 1, 2, 2, 2, 3, 3
非连续最长子序列3
   a, A, B, 3, 4, C, D
A  0, 1, 0, 0, 0, 0, 0
B  0, 0, 2, 0, 0, 0, 0
1  0, 0, 0, 0, 0, 0, 0
C  0, 0, 0, 0, 0, 1, 0
2  0, 0, 0, 0, 0, 0, 0
连续最长子序列2

相关文章

  • LCS:最长公共子序列

    LCS(最长公共子序列)是动态规划里的一道经典的问题。动态规划

  • 深度透析最长公共子序列算法

    最长公共子序列(Longest Common Subsequenen, LCS) 1、概念 动态规划(dynami...

  • 最长公共子序列

    最长公共子序列(Longest Common Subsequence,简称 LCS)是非常经典的动态规划题目。通常...

  • 最长递增子序列: 动态规划和LCS(最长公共子序列)

    最长递增子序列: 动态规划和LCS(最长公共子序列)子序列和子串的区别:子序列不连续,字串连续。这个题两种解法 动...

  • 子序列

    最长公共子序列(LCS)(lintcode 77) 描述:给出两个字符串,找到最长公共子序列(LCS),返回LCS...

  • lintcode 最长公共子序列

    给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。说明最长公共子序列的定义: 最长公共子序列问题是在...

  • 动态规划--最长公共子序列

      动态规划是解决一类问题的方法,而不是某种固定的算法。 eg: 求最长公共子序列(LCS: Longest Co...

  • 动态规划相关算法合集

    动态规划之最长公共子序列:最长公共子序列[https://mp.weixin.qq.com/s/clPncFZT0...

  • LCS问题

    LCS问题包括最长公共子序列和最长公共子串,其中,最长公共子串要求必须连续。 对于二者的求解方式 最长公共子序列:...

  • 最长公共子序列(LCS)——动态规划

    问题描述   子序列是指,从序列中选出一些子元素,需满足其前后关系与在原序列中相同;公共是指该序列同时是两个序列的...

网友评论

    本文标题:动态规划—LCS最长公共子序列

    本文链接:https://www.haomeiwen.com/subject/kjwibctx.html