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

动态规划求解最长公共子序列

求解最长公共子序列问题

1.暴力求解

2.动态规划

状态转移方程

dp[i][j]=          0                                           i=0 或j=0

                      max{dp[i-1][j],dp[i][j-1]}         xi!=yj

                     dp[i-1][j-1]+1                           xi=yj

    

代码

public static int findLCS(String A,  String B) {
        int n=A.length();
        int m=B.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                dp[i][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];
    }

    public static void main(String[] args) {
        String str1="ABCBDAB";
        String str2="BDCABA";
        int lcs = findLCS(str1, str2);
        System.out.println(lcs);

    }

输出最长公共公共子序列的代码:

package com.fantaike;

public class test17 {
    public static int findLCS(String A,  String B,int[][] dp,String[][] direct) {
        int n=A.length();
        int m=B.length();
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                dp[i][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;
                    direct[i][j]="↖";
                } else if(dp[i-1][j]>=dp[i][j-1]) {
                    dp[i][j] = dp[i-1][j];
                    direct[i][j]="←";
                }else{
                    dp[i][j] = dp[i][j-1];
                    direct[i][j]="↑";
                }
            }
        }
        return dp[n][m];
    }
    public static void print_lcs(String[][] direct,String str1,int i,int j){

        if(i==0|| j==0){
            return ;
        }
        if(direct[i][j].equals("↖")){
            print_lcs(direct,str1,i-1,j-1);
            System.out.print(str1.charAt(i-1)+" ");
        }else if(direct[i][j].equals("↑")){
            print_lcs(direct,str1,i,j-1);
        }else{
            print_lcs(direct,str1,i-1,j);
        }
    }



    public static void main(String[] args) {
        String str1="ABCBDAB";
        String str2="BDCABA";
        int n=str1.length();
        int m=str2.length();
        int[][] dp = new int[n + 1][m + 1];
        String[][] direct=new String[n+1][m+1];
        int lcs = findLCS(str1, str2,dp,direct);
        System.out.println("最长公共子序列的个数: "+lcs);
        System.out.println("最长公共子序列 ");
        print_lcs(direct,str1, n,m);
        
    }


}

使用两个pre和cur两个数组优化空间

public static int findLCS(String A,  String B) {
        int n=A.length();
        int m=B.length();
        int[][] dp = new int[2][m + 1];
        int pre=0;
        int cur=1;
        for(int i=0;i<m+1;i++){
            dp[0][i]=0;
        }
        dp[1][0]=0;
        int temp;

        for (int i = 1; i <=n; i++) {
            for (int j = 1; j <= m; j++) {
                if (A.charAt(i -1) == B.charAt(j - 1)) {
                    dp[cur][j] = dp[pre][j - 1] + 1;
                } else {
                    dp[cur][j] = Math.max(dp[pre][j],dp[cur][j-1]);
                }
            }
            temp=pre;
            pre=cur;
            cur=temp;

            System.out.println("pre: "+pre+" cur: "+cur);
        }
        return dp[pre][m];
    }
    

    public static void main(String[] args) {
        String str1="ABCBDAB";
        String str2="BDCABA";
        int lcs = findLCS(str1, str2);
        System.out.println(lcs);

    }

空间优化,只使用一个数组

https://blog.csdn.net/qq_37341466/article/details/83036039   看不懂!   下来慢慢看

参考文献

https://blog.csdn.net/qbyhqp/article/details/82050535

https://blog.csdn.net/u013241673/article/details/79981934

空间优化参考

https://blog.csdn.net/qq_37341466/article/details/83036039

猜你喜欢

转载自blog.csdn.net/u011243684/article/details/87939907