题目描述
给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。
示例1
输入
"1AB2345CD","12345EF"
返回值
"2345"
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) {
//记录最大公共子串记录
StringBuilder sb = new StringBuilder();
int start = 0;
int end = 1;
//str1.substring(start,end) 是左闭右开的 想要substring str1整体字符串 end就得length+1
while(end < str1.length()+1){
//如果str2包含str1截取的部分
if(str2.contains(str1.substring(start,end))){
//如果最大公共子串的长度 < 上一步中公共子串str1截取的长度
//那么sb清空,重新记录公共子串
if(sb.length() < (end - start)){
sb.delete(0,sb.length());
//截取[start,end)之间的字符串,追加到sb中
sb.append(str1,start,end);
//已提交的代码中 没有在此处加end++ 会导致比较长度一次循环 然后再进行第二次循环才会end++滑动窗口
end++;
}else{
//当前序的滑动窗口start向后滑动后,会存在sb.length() >= (end - start)的情况
//即最长公共子串会碰撞长度相同的情况 此时滑动窗口end位置后移
end++;
}
}else{
//向后滑动窗口的起始位置
//这个算法我曾经疑惑,假如出现start>end,程序不是会crash么
//通过debug发现,当start==end时,substring获取的是"",此时contains必然为true
//所以当start == end时,必然会走end++分支
start++;
}
}
//如果最长公共子串记录为0 那么说明没有公共子串
if(sb.length() == 0){
return "-1";
}
return sb.toString();
}
}