1.最长公共子串
求两个字符串的最长公共子串,采用动态规划的算法求解.
我们用一个二维数组dp[i][j]表示第一个字符串的前i个字符和第二个字符串的前j个字符的最长公共字符串的长度.需要确定初始值,也就是这个二维数组的边界值,显然,dp[i][0] = 0, dp[0][j] = 0.但是这没有意义,因为我们找公共子串的起点是比较两个字符串的第一个元素,如果相等,再继续向后遍历.所以dp[i][1] = 1, if s1[i-1] = s2[0], 否则为0,这才是真正的初始条件.这个时间复杂度为O(n1),再固定第一行,遍历列,时间复杂度是O(n2).接下来是得到递推公式,这个我们分析一下.
如果我们想要得到dp[i][j]的值,也即是s1的前i个字符和s2的前j个字符的最大公共字符串的长度,我们需要知道s1[i-1]和s2[j-1]是否相等,如果相等,那么dp[i][j] = dp[i-1][j-1] + 1.否则,dp[i][j] = 0.设计一个临时变量maxLen,每次存储最大的dp[i][j]的值.如果我们想要得到这个最长的公共子串,就再设置一个临时变量,将此时的i或j保存一下,然后将s1从i-1-dp[i][j]开始遍历到i-1即可.
暴力法的时间复杂度太高.
对于两个字符串,我们找最长的公共字符串的时候,是固定一个字符串,遍历另一个字符串,当这两个字符串在某一个下标开始匹配的时候,这个时候再分别让两个字符串的下标各增1,再分别比较,知道某一个下标它们的字符不匹配为止或者超过了某一个字符串的边界为止.这是暴力的解法它的复杂度为O(n^3)
public class FindLongestSubString {
public static int[] maxLong(String str1, String str2){
if(str1 == null || str2 == null || str1.length() == 0 || str2.length() == 0){
return null;
}
int max = 0;
int maxI = -1;
int [][] dp = new int[str1.length()+1][str2.length()+1];
for(int i = 1; i <=str1.length(); i++){
dp[i][0