Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Big O notation - Cracking the Coding Interview

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. :)

like image 371
Esdras Lopez Avatar asked Aug 14 '16 09:08

Esdras Lopez


People also ask

How do you practice Cracking the Coding Interview?

You can use popular online resources like TopCoder, Codechef and Leetcode to expose yourself to different types of questions. Picking up a good programming book specifically focused on interview problems asked at FAANG and tier-1 companies can give you an insightful peek into what to expect at these interviews.

Is Big O notation important in interviews?

While knowledge of Big O Notation is mostly only relevant to the interview process of larger tech firms, it is still well worth knowing how to make your algorithms as fast as possible. Understanding how to write more efficient algorithms and why they're more efficient is helpful at every level!

Is it worth reading Cracking the Coding Interview?

Cracking the Coding Interview gives you a great birds-eye view of the relevant data structures and algorithms, but it doesn't get deep enough into the fundamentals. When you enter a coding interview, there is a slim chance you are going to get a problem that you have seen before.

What is Big O notation in coding?

Big O notation is used in Computer Science to describe the performance or complexity of an algorithm. Big O specifically describes the worst-case scenario, and can be used to describe the execution time required or the space used (e.g. in memory or on disk) by an algorithm.


2 Answers

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.

like image 192
johnnyaug Avatar answered Oct 06 '22 13:10

johnnyaug


In general the printing of a constant length string is considered constant as well, but if we want to be precise let's consider the print of a single character as the basic operation: this means that to print a k length string we have O(k).

Since we have O(ck) possible strings and for each of them we have to check if it is sorted (with O(k)) and to print them (another O(k)), the total complexity became O(ck(k + k)) = O(2ckk).

But multiplying a function for a constant factor doesn't change it's complexity, and therefore the answer remains O(ckk).

like image 26
SimoV8 Avatar answered Oct 06 '22 13:10

SimoV8