动态规划求解最长公共子序列
求解最长公共子序列问题
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
空间优化参考