最长公共子序列

来源:互联网 发布:加内特08年总决赛数据 编辑:程序博客网 时间:2024/06/18 18:30

给定两个字符串str1和str2,返回两个字符串的最长公共子序列。

时间复杂度O(m*n),空间复杂度O(m*n).

如果只想求最长公共子序列长度,可以使用空间压缩的方法将额外空间复杂度降到O(min{m,n}).


private static String lcse(String str1,String str2){    if(str1 == null || str1.length()==0 ||str2 == null || str2.length() == 0){        return "";    }    char[] arr1 = str1.toCharArray();    char[] arr2 = str2.toCharArray();    int[][] dp = getDP(arr1,arr2);    int m = arr1.length-1;    int n = arr2.length-1;    char[] res = new char[dp[m][n]];    int index = res.length-1;    //根据dp数组还原最长子序列    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--] = arr1[m];            m--;            n--;        }    }    return String.valueOf(res);}//dp[i][j]代表str1[0...i]与str2[0...j]的最长公共子序列private 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 i=1;i<str2.length;i++){        dp[0][i] = Math.max(dp[0][i-1],str1[0]==str2[i]?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;}

原创粉丝点击