题目:
给定两个字符串str1和str2,返回两个字符串的最长公共子序列。
举例str1=”1A2C3D4B56”,str=“B1D23CA45B6A”。123456或者12C4B6都是最长公共子序列,返回哪一个都行。
思路:
此题可以采用动态规划的思想来解。首先要构造一个矩阵Matrix[str1.length()][str2.length()]。以str1为行,str2为列。之后构造数组dp[str1.length()][str2.length()]用于记录最长匹配字符串的长度。首先要算出dp[0][0]的值之后算出第一行或者是第一列的dp值。dp[0][0]的值通过以下公式计算:
dp[0][0] = str1.charAt(0) == str2.charAt(0)?1:0;
之后计算第一列的最长公共序列的长度,实质上就是比较str2[0]与str1[0~i-1]。若str2[0]与某一项str1[x]相等则设dp[x][0]为1.之后的dp[i+1~str1.length()-1]均为1.因为比较的是str2[0],长度最大为1.列上的同理。
之后要解决i,j大于等于1上的数据了。需要考虑三种情况:
- str1[i]!= str2[j],dp[i-1][j]大于dp[i][j-1],则dp[i][j]为dp[i-1][j].
- str1[i]!= str2[j],dp[i][j-1]大于dp[i-1][j],则dp[i][j]为dp[i][j-1].
- str1[i]== str2[j],dp[i][j] = dp[i-1][j-1]+1与dp[i][j]的最大值。
解题代码:
public int [][]Solution(String str1,String str2){
int [][] dp = new int [str1.length()][str2.length()];
for(int i=0;i<str1.length();i++){
Arrays.fill(dp[i], 0);
}
dp[0][0] = str1.charAt(0) == str2.charAt(0)?1:0;
for(int i=1;i<str1.length();i++){
dp[i][0] = Math.max(dp[i-1][0], str1.charAt(i) == str2.charAt(0)?1:0);
}
for(int j=1;j<str2.length();j++){
dp[0][j] = Math.max(dp[0][j-1], str1.charAt(0) == str2.charAt(j) ?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.charAt(i) == str2.charAt(j)){
dp[i][j] = Math.max(dp[i][j], dp[i-1][j-1]+1);
}
}
}
return dp;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
problem1 p1 = problem1.class.newInstance();
String str1 = new String("1A2C3D4B56");
String str2 = new String("B1D23CA45B6A");
int [][] dp = p1.Solution(str1, str2);
int m = str1.length()-1;
int n = str2.length()-1;
char [] res = new char[dp[m][n]];
int index = res.length-1;
while(index >= 0){
if(m>0 && dp[m][n] == dp[m-1][n]){
m--;
}else if(n>0 && dp[m][n] == dp[m][n-1]){
n--;
}else{
res[index--] = str1.charAt(m);
m--;
n--;
}
}
System.out.println(String.valueOf(res));
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}