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();
}
From: problem
MY CALCULATION:
The first loop has (str.length - 1) rotations. 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. If we let N=str.length. In the first loop, we have (N-1) ~ N, thus a total of ~N^3. But then we have to assume that inside both the loops, it is O(1) otherwise we have have > 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
.
The external loop can be approximated (as you did) to 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.
So if you DON'T consider what happens internally in substring
and replaceAll
methods the complexity is O(n) * O(n) -> O(n^2).
Note that the replaceAll
iterate over the whole string, so his internal complexity is O(n). Considering also this the complexity is O(n^3).
Assuming n
is length of str
, you get:
n - 1
times: O(n) n - 1
times, so on average n / 2
times: O(n) replaceAll()
inside countVowels()
iterates over 2 to n
characters, so on average n / 2 + 1
times: O(n) Note: Performance of substring()
depends on version of Java , so it is either O(1) (earlier Java) or O(n) (later 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()
.
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 )
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
. Since only fastest growing factor counts, that means O(n 2 )
Iteration sum: Sum the iterations of inner loop, ie 1 + 2 + ... + n-1
. Sum of a sequence can be calculated as count * average
, and average can be calculated as (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 )
As you can see, O math was simpler, so that's why it was chosen for the answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.