Issue
I need help understanding how the author got the answer of problem 11 in the Big O chapter.
The problem goes like this:
The following code prints all strings of length k where the characters are in sorted order. It does this by generating all strings of length k and then checking if each is sorted. What is its runtime?
public static int numChars = 26;
public static void printSortedStrings(int remaining) {
printSortedStrings(remaining, "");
}
public static void printSortedStrings(int remaining, String prefix) {
if (remaining == 0) {
if (isInOrder(prefix)) {
System.out.println(prefix); // Printing the string
}
} else {
for (int i = 0; i < numChars; i++) {
char c = ithLetter(i);
printSortedStrings(remaining - 1, prefix + c);
}
}
}
public static boolean isInOrder(String s) {
for (int i = 1; i < s.length(); i++) {
int prev = ithLetter(s.charAt(i - 1));
int curr = ithLetter(s.charAt(i));
if (prev > curr) {
return false;
}
}
return true;
}
public static char ithLetter(int i) {
return (char) (((int) 'a') + i);
}
public static void main(String[] args) {
printSortedStrings(2);
}
Book answer:
O(kck), where k is the length of the string and c is the number of characters in the alphabet. It takes O(ck) time to generate each string. Then, we need to check that each of these is sorted, which takes O(k) time.
Notice that printing the string is not taken into account in the answer above, but I've seen the opposite in other problems.
When do you take into account printing the string in the runtime?
Would this be the correct answer O(k2ck)?
Also, any advice on being able to quickly tell that there's an exponential part in the runtime of this code would be greatly appreciated. :)
Solution
In short, no. The correct answer is O(kck) as in the book.
After you went over a string to check if its characters were ordered, which would take O(k), printing it would add only O(k) - which does not change your complexity.
Suppose testing whether a string is ordered takes a*k
operations, and printing it takes b*k
. Then the total number of operations for each string is at most (a+b)*k
which is still O(k).
Edit: Regarding the second part of your question, going over all words with some fixed length will result in an exponential runtime complexity, since there are ck such words where c
is the size of the alphabet and k
is the length of the word.
Answered By - johnnyaug
Answer Checked By - Clifford M. (JavaFixing Volunteer)