最长公共子串
题刷多了就有很多相似的问题出现了,这种最长的系列都可以作为一个专题了
1 最大连续子数组和
2 最长无重复子串
3 最长公共子串
几乎都是一样的,涉及到两个两个递推,一个是用来更新另一个的。主要是临界条件不好找,基于类似的思想,子串在清零的时候,不能立马清零,因为可能会出现新的子串。
这种比较尬的测试样例就明白了:acdem712345678xxx 与 m71a12345678c
public String LCS (String str1, String str2) {
// write code here
if(str1==null || str2==null){
return null;
}
String stra=str1.length()>str2.length()?str1:str2;
String strb=str1.length()<=str2.length()?str1:str2;
char []chara=stra.toCharArray();
StringBuffer sb=new StringBuffer(strb);
StringBuffer [] tmp=new StringBuffer [chara.length];
initStringArray(tmp);
StringBuffer [] dp=new StringBuffer [chara.length];
initStringArray(dp);
for(int i=0;i<chara.length;i++){
StringBuffer s1=new StringBuffer(String.valueOf(chara[i]));
if(i==4317){
System.out.println("");
}
if(i==0){
if(isSubstr(tmp[i],s1,sb)){
dp[i]=dp[i].append(s1);
}
tmp[i]=tmp[i].append(s1);
}else{
if(isSubstr(tmp[i-1],sb,s1)){
tmp[i]=tmp[i-1].append(s1); //如果加上当前字符是连续公共子串,更新 tmp
}else{
tmp[i]= tmp[i].helper(tmp[i-1],sb,s1); // 如果加上当前子串不是连续公共子串,不能立马清零,要在这一块小的区域里面找一下可能会连续的子串
}
dp[i]=dp[i-1].toString().length()>=tmp[i].toString().length()?dp[i-1]:tmp[i];
}
}
return dp[chara.length-1].toString();
}
public void initStringArray(StringBuffer [] strArray){ //初始化
for(int i=0;i<strArray.length;i++){
strArray[i]=new StringBuffer("");
}
}
public boolean isSubstr(StringBuffer s1,StringBuffer s2,StringBuffer s){ //一个字符串是不是另一个字符串的子串
String str1=new StringBuffer(s1).append(s).toString();
String str2=s2.toString();
return str2.contains(str1);
}
public String helper(StringBuffer s1,StringBuffer s2,StringBuffer s){
String str1=new StringBuffer(s1).append(s).toString();
String str2=s2.toString();
String res=null;
for(int i=1;i<str1.length();i++){
String tmp=str1.substring(i);
if(str2.contains(str1)){
res=tmp;
break;
}else{
continue;
}
}
return res;
}
查看23道真题和解析