【发布时间】:2016-10-16 12:35:27
【问题描述】:
我遇到了以下看起来很完美的程序。在我看来,它的时间复杂度是 nlogn,其中 n 是字符串的长度。
n 用于存储不同的字符串,nlog 用于排序,n 用于比较。所以时间复杂度是nlogn。 存储n个子串的空间复杂度为n
我的问题是可以进一步优化吗?
public class LRS {
// return the longest common prefix of s and t
public static String lcp(String s, String t) {
int n = Math.min(s.length(), t.length());
for (int i = 0; i < n; i++) {
if (s.charAt(i) != t.charAt(i))
return s.substring(0, i);
}
return s.substring(0, n);
}
// return the longest repeated string in s
public static String lrs(String s) {
// form the N suffixes
int n = s.length();
String[] suffixes = new String[n];
for (int i = 0; i < n; i++) {
suffixes[i] = s.substring(i, n);
}
// sort them
Arrays.sort(suffixes);
// find longest repeated substring by comparing adjacent sorted suffixes
String lrs = "";
for (int i = 0; i < n-1; i++) {
String x = lcp(suffixes[i], suffixes[i+1]);
if (x.length() > lrs.length())
lrs = x;
}
return lrs;
}
public static void main(String[] args) {
String s = "MOMOGTGT";
s = s.replaceAll("\\s+", " ");
System.out.println("'" + lrs(s) + "'");
}
}
【问题讨论】:
-
如果代码已经在运行,那么它可能属于Code Review。
-
您可以通过不创建尽可能多的子字符串来使其更快(尽管不是渐近的)。例如,
lcp可以只返回前缀长度,而您保留i和该返回值以存储“迄今为止的最大值”。 -
安迪是对的。实际上,当您创建所有子字符串时,它已经是 O(n^2),而当您对后缀进行排序时,它实际上是 O(n^2 logn)
标签: java string algorithm suffix-tree