//获得最长公共子串问题
public class MaxSameLenSequen{
//构建动态规划表
public static int[][]getDp(char[]str1,char[]str2)
{
//(dp[i][j]的含义i,j作为最后一个字符,公共子串有多长)
int[][]dp=new int[str1.length][str2.length];
//第一行的计算
for(int i=0;i<str2.length;i++)
{
if(str1[0]==str2[i])
{
dp[0][i]=1;
}
}
//第一列的计算
for(int j=1;j<str1.length;j++)
{
if(str1[j]==str2[0])
{
dp[j][0]=1;
}
}
//其他位置的计算
for(int i=1;i<str1.length;i++)
{
for(int j=1;j<str2.length;j++)
{
if(str1[i]==str2[j])
{
dp[i][j]=dp[i-1][j-1]+1;
}
}
}
return dp;
}
//获得最长公共子串(时间复杂度O(m*n),空间复杂度O(M*n))
public static String MaxSameLen(String str1,String str2)
{
if(str1==null||str2==null||str1.equals("")||str2.equals(""))
{
return "";
}
char[]ch1=str1.toCharArray();
char[]ch2=str2.toCharArray();
int[][]dp=getDp(ch1,ch2);
int end=0;
int max=0;
for(int i=0;i<ch1.length;i++)
{
for(int j=0;j<ch2.length;j++)
{
if(dp[i][j]>max)
{
end=i;
max=dp[i][j];
}
}
}
return str1.substring(end-max+1,end+1);
}
//**************************************************************
//获得最长公共子串(对角线解法)(时间复杂度O(m*n),空间复杂度O(1))
public static String MaxSameLen02(String str1,String str2)
{
if(str1==null|str2==null||str1.equals("")||str2.equals(""))
{
return "";
}
char[]ch1=str1.toCharArray();
char[]ch2=str2.toCharArray();
int row=0; //斜线开始的位置的行
int col=ch2.length-1; //斜线开始的位置的列
int max=0; //记录最大的长度
int end=0; //最大长度更新时,记录子串的结尾位置
while(row<ch1.length)
{
int i=row;
int j=col;
int len=0;
//从(i,j)开始向右下方遍历
while(i<ch1.length&&j<ch2.length)
{
if(ch1[i]!=ch2[j])
{
len=0;
}
else{
len++;
}
//记录最大值
if(len>max)
{
end=i;
max=len;
}
//斜线位置计算
i++;
j++;
}
if(col>0)
{
col--;//斜线开始的位置的列向左下方移动
}
else{
row++;//斜线开始的行从向下移动
}
}
return str1.substring(end-max+1,end+1);
}
public static void main(String[]args)
{
String str1="abcde";
String str2="bebcd";
//System.out.println(str1.substring(1,3));
System.out.println(MaxSameLen(str1,str2));
System.out.println(MaxSameLen02(str1,str2));
}
}