public class Solution {
public String LCS (String s1, String s2) {
int len1 = s1.length();
int len2 = s2.length();
// dp[i][j]记录s1长度为i,s2长度为j的最长公共子序列长度
int[][] dp = new int[len1 + 1][len2 + 1];
for(int i = 1; i <= len1; i++){
for(int j = 1; j <= len2; j++){
if(s1.charAt(i - 1) == s2.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]);
}
}
}
// 此时最长公共子序列的长度为dp[len1][len2]
// 倒推LCS ,即从i = len1,j = len2开始往后推
// 当s1.charAt(i - 1) == s2.charAt(j - 1)时,将该字符并入LCS串
// 当s1.charAt(i - 1) != s2.charAt(j - 1)时,
// 判断dp[i][j]这个状态是由dp[i - 1][j]转移过来的,
// 还是由dp[i][j - 1]转移过来的。
// 所以我们判断dp[i - 1][j]和dp[i][j - 1]的大小,
// 当dp[i - 1][j] > dp[i][j - 1]时,说明是从dp[i - 1][j]转移过来的,
// 则我们回退回去,令 i--,反之j--,重复这个操作到结束。
int i = len1;
int j = len2;
StringBuffer sb = new StringBuffer();
while(i != 0 && j != 0){
if(s1.charAt(i - 1) == s2.charAt(j - 1)){
sb.insert(0, s1.charAt(i - 1));
i--;
j--;
}else if(dp[i - 1][j] > dp[i][j - 1]){
i--;
}else{
j--;
}
}
return sb.length() == 0 ? "-1" : sb.toString();
}
}