[英]Calculate the time complexity of this specific algorithm
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();
}
MY CALCULATION: 我的计算:
The first loop has (str.length - 1) rotations. 第一个循环旋转(str.length-1)。 The second loop depends on the first loop, so it goes like: (0), [0, 1], [0, 1, 2] , ... , [0, 1 .., str.length - 2] Thus this is a total of (Second loop only) 1 + 2 + ... + N - 2 = (2N-3)^2/8 -1/8 ~ (2N)^2.
第二个循环依赖于第一个循环,因此它类似于:(0),[0、1],[0、1、2],...,[0、1 ..,str.length-2]因此这是总计(仅第二个循环)1 + 2 + ... + N-2 =(2N-3)^ 2/8 -1/8〜(2N)^ 2。 If we let N=str.length.
如果我们让N = str.length。 In the first loop, we have (N-1) ~ N, thus a total of ~N^3.
在第一个循环中,我们有(N-1)〜N,因此总计〜N ^ 3。 But then we have to assume that inside both the loops, it is O(1) otherwise we have have > O(N^3)?
但是,我们必须假设在两个循环中,它都是O(1),否则我们有> O(N ^ 3)?
But I don't think this is right. 但是我认为这是不对的。
How do we calculate such a time complexity? 我们如何计算这样的时间复杂度?
If n
is the length of str
. 如果
n
是str
的长度。
The external loop can be approximated (as you did) to O(n)
. 外部循环可以像您所做的那样近似为
O(n)
。
The inner loop can be approximated to O(n) too, because it goes from a minimum of 0 cycles to a maximum of n cyles when length
is 0. 内部循环也可以近似为O(n) ,因为当
length
为0时,它从最小的0个循环到最大的n个循环。
So if you DON'T consider what happens internally in substring
and replaceAll
methods the complexity is O(n) * O(n) -> O(n^2). 因此,如果您不考虑
substring
和replaceAll
方法内部发生的情况,则复杂度为 O(n)* O(n)-> O(n ^ 2)。
Note that the replaceAll
iterate over the whole string, so his internal complexity is O(n). 注意
replaceAll
遍历整个字符串,因此他的内部复杂度为O(n)。 Considering also this the complexity is O(n^3). 还考虑到这一点,复杂度为O(n ^ 3)。
Assuming n
is length of str
, you get: 假设
n
是str
长度,则得到:
n - 1
times: O(n) n - 1
次: O(n) n - 1
times, so on average n / 2
times: O(n) n - 1
次,因此平均重复n / 2
次: O(n) replaceAll()
inside countVowels()
iterates over 2 to n
characters, so on average n / 2 + 1
times: O(n) countVowels()
replaceAll()
内的countVowels()
迭代2到n
字符,因此平均n / 2 + 1
次: O(n) Note: Performance of substring()
depends on version of Java , so it is either O(1) (earlier Java) or O(n) (later Java). 注意:
substring()
性能取决于Java的版本 ,因此它是O(1) (Java的早期版本)或O(n) (Java的后期版本)。 But since O(1) + O(n) and O(n) + O(n) is both O(n) , it makes no difference for performance of inner loop body, which is why the above logic only considers the performance of replaceAll()
. 但是由于O(1) + O(n)和O(n) + O(n)都是O(n) ,所以它对内部循环体的性能没有影响,因此上述逻辑只考虑了
replaceAll()
。
UPDATE UPDATE
There are three ways of calculating performance for outer and inner loop combined, excluding what happens in the body: 有三种方法可以计算外环和内环组合的性能,但不包括主体中发生的情况:
O math: Outer loop is O(n) , and inner loop is O(n) , so total is O(n) * O(n) = O(n 2 ) O数学:外循环为O(n) ,内循环为O(n) ,所以总计为O(n) * O(n) = O(n 2 )
Iteration math: Outer loop iterates n - 1
times, and inner loop iterates n / 2
times (on average) , so total is (n - 1) * (n / 2) = n² / 2 - n / 2
. 迭代数学:外循环迭代
n - 1
次,内循环迭代n / 2
次(平均) ,因此总计为(n - 1) * (n / 2) = n² / 2 - n / 2
。 Since only fastest growing factor counts, that means O(n 2 ) 由于只有增长最快的因子才算,这意味着O(n 2 )
Iteration sum: Sum the iterations of inner loop, ie 1 + 2 + ... + n-1
. 迭代总和:求和内循环的迭代,即
1 + 2 + ... + n-1
。 Sum of a sequence can be calculated as count * average
, and average can be calculated as (min + max) / 2
. 序列的总和可以计算为
count * average
,平均可以计算为(min + max) / 2
。 That means that average = (1 + n-1) / 2 = n / 2
, and sum = (n - 1) * (n / 2)
, which is exactly the same result we got in #2 above, so it is O(n 2 ) 这意味着
average = (1 + n-1) / 2 = n / 2
, sum = (n - 1) * (n / 2)
,这与我们在上面的#2中得到的结果完全相同,因此O(n 2 )
As you can see, O math was simpler, so that's why it was chosen for the answer. 如您所见, O数学更简单,因此才选择答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.