这个 dp 注意一个点 最长子串 和 最长子序列 是不同的概念 最长子串 是需要连续的 所以下一个
dp 的计算只与斜角有关 即 只考虑 包括当前位的当前最长子串 如果当前位不相等 即 str1[i]!=str2[j] 则 dp[i][j]=-1
之前是 dp 直接存 String 结果 超时 所以参考优化了一下改成记录最大长度及开始位置
import java.util.*; public class Solution { /** * longest common substring * @param str1 string字符串 the string * @param str2 string字符串 the string * @return string字符串 */ public String LCS (String str1, String str2) { // write code here if(str1 == null || str2 == null || str1.equals("") || str2.equals("")){ return "-1"; } char[] cstr1=str1.toCharArray(); char[] cstr2=str2.toCharArray(); int N1=cstr1.length; int N2=cstr2.length; int [][] dp=new int[N1][N2]; int max=0; int indexMax=0; if(cstr1[0]==cstr2[0]){ dp[0][0]=1; max=1; }else{ dp[0][0]=-1; } //初始化列表边界 for(int i=1;i<N1;i++){ if (cstr1[i]==cstr2[0]){ dp[i][0]=1; }else { dp[i][0]=-1; } } //初始化行边界 for(int i=1;i<N2;i++){ if (cstr2[i]==cstr1[0]){ dp[0][i]=1; max=1; }else { dp[0][i]=-1; } } //任何一个位置的普遍公式 //末位最近最长子序列 for(int i=1;i<N1;i++){ for(int j=1;j<N2;j++){ if(cstr1[i]==cstr2[j]){ dp[i][j]=(dp[i-1][j-1]==-1?0:dp[i-1][j-1])+1; }else{ dp[i][j]=-1; } if(dp[i][j]!=-1){ if (dp[i][j]>=max){ max=dp[i][j]; indexMax=i; } } } } if (max==0){ return "-1"; } return str1.substring(indexMax-max+1,indexMax+1); } }