【发布时间】:2016-09-21 15:30:44
【问题描述】:
public static String findLongestSubstring(String str) {
for (int len = str.length(); len >= 2; len--) {
for (int i = 0; i <= str.length() - len; i++) {
String substr = str.substring(i, i + len);
int vowels = countVowels(substr);
int consonants = len - vowels;
if (vowels == consonants) {
return substr;
}
}
}
return "";
}
private static int countVowels(String str) {
return str.replaceAll("[^AEIOUaeiou]+", "").length();
}
发件人:problem
我的计算:
第一个循环有 (str.length - 1) 个旋转。第二个循环取决于第一个循环,所以它类似于: (0), [0, 1], [0, 1, 2] , ... , [0, 1 .., str.length - 2] 因此这是总共(仅第二个循环)1 + 2 + ... + N - 2 = (2N-3)^2/8 -1/8 ~ (2N)^2。如果我们让 N=str.length。在第一个循环中,我们有 (N-1) ~ N,因此总共有 ~N^3。但是我们必须假设在两个循环内都是 O(1) 否则我们有 > O(N^3)?
但我认为这是不对的。
我们如何计算这样的时间复杂度?
【问题讨论】:
-
这个算法的目标是什么?
-
外循环的复杂度为 O(n),因为它取决于字符串长度。内部循环还取决于字符串长度(在最坏的情况下),因此它也具有 O(n) 复杂度。内部循环的主体也取决于字符串长度,尽管这并不明显(字符串操作需要遍历所有字符),因此它也具有 O(n) 复杂度。现在你做
outer * inner * body,即O(n) * O(n) * O(n),因此得到O(n^3)。 -
@JonnyHenly 因为常量值在大 O 表示法中无关紧要,它将被简化为
n * n。但是您的计算可能没有考虑到内部循环主体的复杂性。 -
@Thomas,内部循环如何从 1->n-1 迭代?如果它从 1->1 然后 1->2 然后 1->3 ,.... 1->n-1,它不应该是总和 1 + 2 + 3 + ... + (n- 1)?
-
@YOGIYO 你基本上是对的,但是在确定算法的复杂性时,你会考虑最坏的情况并忽略任何常数因素。因此,内部循环仍然取决于字符串长度,导致 O(n) 复杂度。另请参阅 Andreas 的回答。
标签: java algorithm time-complexity