题解 | #最长公共子序列(二)#
最长公共子序列(二)
http://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11
思路: 先动态规划求出最长公共子序列的长度,然后逆向找到相同字符。
代码:
import java.util.*;
public class Solution {
/**
* longest common subsequence
* @param s1 string字符串 the string
* @param s2 string字符串 the string
* @return string字符串
*/
public String LCS (String s1, String s2) {
// write code here
if(s1==null||s2==null||s1.length()==0||s2.length()==0){
return "-1";
}
char[] ss1=s1.toCharArray();
char[] ss2=s2.toCharArray();
int m=ss1.length;
int n=ss2.length;
String res="-1";
int cnt[][]=new int[m+1][n+1];//字符串s1前i个,s2前j个最多相同的字符个数
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(ss1[i-1]==ss2[j-1]){//若当前两个字符相等,则到当前两个字符为止的两个字符串具有的相同字符数等于去掉这两个字符的前面字符串的相同字符数加1
cnt[i][j]=cnt[i-1][j-1]+1;
}else{//若不同,则为去掉s1中最后一个字符或去掉s2中最后一个字符的相同个数的最大值。
cnt[i][j]=Math.max(cnt[i-1][j],cnt[i][j-1]);
}
}
}
int len=cnt[m][n];
int i=m-1,j=n-1;
StringBuilder sb=new StringBuilder();
while(i>=0&&j>=0){
if(ss1[i]==ss2[j]){
sb.append(String.valueOf(ss1[i]));
i--;
j--;
}else{
if(cnt[i][j+1]>=cnt[i+1][j]){
i--;
}else{
j--;
}
}
}
sb.reverse();
if(sb.length()!=0){
res=sb.toString();
}
return res;
}
}