DP29 最长相同子串 Longest Common Substring @geeksforgeeks
2013-12-29 03:30
459 查看
Given two strings ‘X’ and ‘Y’, find the length of the longest common substring. For example, if the given strings are “GeeksforGeeks” and “GeeksQuiz”, the output should be 5 as longest common substring is “Geeks”
Let m and n be the lengths of first and second strings respectively.
A simple solution is to one by one consider all substrings of first string and for every substring check if it is a substring in second string. Keep track of the maximum length substring. There will be O(m^2) substrings and we can find whether
a string is subsring on another string in O(n) time (See this). So overall time complexity
of this method would be O(n * m2)
Dynamic Programming can be used to find the longest common substring in O(m*n) time. The idea is to find length of the longest common suffix for all substrings of both strings and store these lengths in a table.
The longest substring can also be solved in O(n+m) time using Suffix Tree. We will be covering Suffix Tree based solution in a separate post.
思路:
1 暴力枚举 O(m^2 * n):在长度为m的string里枚举所有子串需要O(m^2),对于每一个子串要在另一个长度为n的string里找相同,用KMP需要O(n)
2 DP 把求相同子串的问题转为求相同后缀的问题 O(m*n)
3 后缀树: O(m+n)
参考 https://en.wikipedia.org/wiki/Longest_common_substring_problem
DP:
package DP;
public class LongestCommonSubstring {
public static void main(String[] args) {
String X = "OldSite:GeeksforGeeks.org";
String Y = "NewSite:GeeksQuiz.com";
int m = X.length();
int n = Y.length();
System.out.println(LCSubstr(X, Y, m, n));
}
// Time Complexity: O(m*n) Time Complexity: O(m*n)
public static int LCSubstr(String X, String Y, int m, int n) {
// Create a table to store lengths of longest common suffixes of
// substrings. Note that LCSuff[i][j] contains length of longest
// common suffix of X[0..i-1] and Y[0..j-1]. The first row and
// first column entries have no logical meaning, they are used only
// for simplicity of program
int[][] LCSuff = new int[m + 1][n + 1];
int longest = 0;
// To store length of the longest common substring
/* Following steps build LCSuff[m+1][n+1] in bottom up fashion. */
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
LCSuff[i][j] = 0;
} else if (X.charAt(i - 1) == Y.charAt(j - 1)) {
LCSuff[i][j] = LCSuff[i - 1][j - 1] + 1;
longest = Math.max(longest, LCSuff[i][j]);
} else {
LCSuff[i][j] = 0;
}
}
}
return longest;
}
}
http://www.geeksforgeeks.org/longest-common-substring/
Let m and n be the lengths of first and second strings respectively.
A simple solution is to one by one consider all substrings of first string and for every substring check if it is a substring in second string. Keep track of the maximum length substring. There will be O(m^2) substrings and we can find whether
a string is subsring on another string in O(n) time (See this). So overall time complexity
of this method would be O(n * m2)
Dynamic Programming can be used to find the longest common substring in O(m*n) time. The idea is to find length of the longest common suffix for all substrings of both strings and store these lengths in a table.
The longest common suffix has following optimal substructure property LCSuff(X, Y, m, n) = LCSuff(X, Y, m-1, n-1) + 1 if X[m-1] = Y[n-1] 0 Otherwise (if X[m-1] != Y[n-1]) The maximum length Longest Common Suffix is the longest common substring. LCSubStr(X, Y, m, n) = Max(LCSuff(X, Y, i, j)) where 1 <= i <= m and 1 <= j <= n
The longest substring can also be solved in O(n+m) time using Suffix Tree. We will be covering Suffix Tree based solution in a separate post.
思路:
1 暴力枚举 O(m^2 * n):在长度为m的string里枚举所有子串需要O(m^2),对于每一个子串要在另一个长度为n的string里找相同,用KMP需要O(n)
2 DP 把求相同子串的问题转为求相同后缀的问题 O(m*n)
3 后缀树: O(m+n)
参考 https://en.wikipedia.org/wiki/Longest_common_substring_problem
DP:
package DP;
public class LongestCommonSubstring {
public static void main(String[] args) {
String X = "OldSite:GeeksforGeeks.org";
String Y = "NewSite:GeeksQuiz.com";
int m = X.length();
int n = Y.length();
System.out.println(LCSubstr(X, Y, m, n));
}
// Time Complexity: O(m*n) Time Complexity: O(m*n)
public static int LCSubstr(String X, String Y, int m, int n) {
// Create a table to store lengths of longest common suffixes of
// substrings. Note that LCSuff[i][j] contains length of longest
// common suffix of X[0..i-1] and Y[0..j-1]. The first row and
// first column entries have no logical meaning, they are used only
// for simplicity of program
int[][] LCSuff = new int[m + 1][n + 1];
int longest = 0;
// To store length of the longest common substring
/* Following steps build LCSuff[m+1][n+1] in bottom up fashion. */
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
LCSuff[i][j] = 0;
} else if (X.charAt(i - 1) == Y.charAt(j - 1)) {
LCSuff[i][j] = LCSuff[i - 1][j - 1] + 1;
longest = Math.max(longest, LCSuff[i][j]);
} else {
LCSuff[i][j] = 0;
}
}
}
return longest;
}
}
http://www.geeksforgeeks.org/longest-common-substring/
相关文章推荐
- spoj1811 Longest Common Substring(LCS)最长公共子串
- 最长公共子串(Longest Common Substring)
- LeetCode 5 Longest Palindromic Substring(最长回文子串,暴力剪枝/DP/曼彻斯特算法)
- spoj1811 Longest Common Substring(LCS)最长公共子串
- spoj1811 Longest Common Substring(LCS)最长公共子串
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
- 最长公共子串(Longest-Common-Substring)
- spoj1811 Longest Common Substring(LCS)最长公共子串
- 利用后缀数组(suffix array)求最长公共子串(longest common substring)
- spoj1811 Longest Common Substring(LCS)最长公共子串
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- spoj1811 Longest Common Substring(LCS)最长公共子串
- spoj1811 Longest Common Substring(LCS)最长公共子串
- hdu1403---Longest Common Substring(后缀数组求2个字符串的最长公共子串)
- lintcode :longest common substring 最长公共子串
- 最长公共子串(Longest common substring)
- SPOJ 1812 Longest Common Substring II 后缀自动机求多字符串最长公共子串
- spoj1811 Longest Common Substring(LCS)最长公共子串
- spoj1811 Longest Common Substring(LCS)最长公共子串