题解 | #二叉树中和为某一值的路径(三)#
最长公共子串
http://www.nowcoder.com/practice/f33f5adc55f444baa0e0ca87ad8a6aac
解题思路:
1.创建二维boolean型数组,当str1.charAt(i) == str2.charAt(j) 时,dp[i][j]==true
2.对于公共子串,其必定是连续的,所以当dp[i][j]==true时,dp[i++][j++]==true也成立,通过i++,j++遍历dp数组,并记录length,如果length >maxlength,用end标记结束索引
3.还有一个细节很重要,一个公共子串找出来后,还要继续遍历数组,寻找下一个,所以,length要重置为0,i 和 j也要回退到原来的状态
4.最后由最长公共子串的长度和结束索引,可以得到初始索引,从初始索引开始拼接即可
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) {
int m = str1.length();
int n = str2.length();
int length = 0;
int maxlength = 0;
int end = 0;
boolean[][] dp = new boolean[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
dp[i][j] = str1.charAt(i) == str2.charAt(j);
}
}
//遍历dp数组,寻找最长公共子串
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(dp[i][j] == true){
//对于连续的公共子串,dp[i][j] == true时,必有 dp[i + 1][j + 1] == true
while(i < m && j < n && dp[i][j]){//i < m && j < n 防止数组越界
length++;
i++;
j++;
}
if(length > maxlength){
maxlength = length; //maxlength记录最长子串的长度
end = i - 1;//已知长度和结束索引,可以求得初始索引
//一个公共子串结束后,将length置为0,重新记录下一个公共子串的长度,同时i j要回退,保证返回for循环时是按顺序的
while(length != 0){
length--;
i--;
j--;
}
}
else{
while(length != 0){//即使length < maxlength,也要将length置为0,重新记录下一个公共子串的长度
length--;
i--;
j--;
}
}
}
}
}
//根据end 和 maxlength,可以得到初始索引,从初始索引开始,拼接字符串
StringBuilder res = new StringBuilder();
for(int i = (end - maxlength + 1); i <= end; i++)
res.append(str1.charAt(i));
return res.toString();
}
}