题刷多了就有很多相似的问题出现了,这种最长的系列都可以作为一个专题了
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; }