Guess what? Recently Facebook’s recruiting team visited NYU Tandon School of Engineering, where your humble servant is residing almost every day. Three events were scheduled: breakfast with engineers, cracking coding interview, and resume discussion with those same engineers. One needed to RSVP for the first and latter one in order to get there. Just to say, I wasn’t the one.

Anyway, I was happy enough to get to the Cracking the Coding Interview presentation (Honestly, I had to break a speed limit for couple miles to be there in time. And I was late…). A very nice recruiter told us why we should apply to Facebook, what kind of great company Facebook is, etc. Did she even needed to wet anyone’s appetite? I do not think so.

Interview tips

Without further ado, I want to share with you my sacred knowledge! Open your mind and soak these ultimate tips into your spongy brain!

0. Be yourself - Make yourself comfy. Be a person, not a robot with learned reflexes! (Probably, this is the hardest part for me. Usually I get extremely nervous during such kind of events. But this is who I am, cannot do anything about it! =) )

1. Ask questions! - Yep! Ask lots of questions until the problem statement seems to be crystal clear. The engineer said that sometimes questions are stated in a slightly ambiguous way, so it is your work to clarify and find all possible caveats in them. Interestingly, he said that it is even okay to ask about data structures that you are not familiar with… Or I got him wrong.

2. Propose a solution - Do not write anything yet. Just propose an idea and simulate the solution on a given example. This will help a lot in case you misunderstood the problem. Also, this shows your communication skills. Good engineers are good speakers and explainers! Also, say what you are thinking about, this will let the recruiter know that you are still with him and have not escaped to the darkest corner of your brain in search of salvation.

3. Write down the solution - Now you have to show what your have taken out from those insanely expensive calligraphy lessons! Take a marker and create art! As the audience was assured, this skill is not given to one from birth, and one need to put some effort to develop it.

4. Run your solution on the test case - Simulate how your algorithm works on a given test case. Have you taken into account all the corner cases?

5. Say that you’ve finished - If you are pretty sure that your masterpiece is ready, say it.

?. Perform complexity analysis - I forgot where should I put this. I guess this should be accompany every phase.

Probably, I have missed something, but I think essential part is still there.

Funny thing

The engineers staged a mock interview. Which was actually really helpful. Now at least you know what to expect.

And the funny thing is that their complexity analysis was wrong! I think it was unintentional. They just were too relaxed, they were not in desperate search of job. I smelled something fishy when the engineers commented on the time complexity. I knew the estimate was wrong, but I couldn’t say exactly why. By the time I realized what was the problem, they had already moved forward, so I did not bother to interrupt.

Problem

Your are given a binary tree where each node contains a letter. Write an algorithm which prints all the paths from the root to leaves.

So if you have something like this:

Then your program should print out:

A B E



A D F



A D G

Solution

Stage one. Ask questions. Valid questions are:

Do I need to print them out in any particular order? - No



Are there any loops? - No



Can I use additional memory? - Yes

Stage two. Propose a solution.

We are going to use a stack to keep characters from visited nodes on the path. Whenever we visit a leaf, we print out all the letters in the stack. That is it.

Stage three. Write down.

typedef struct Node { Node *left_child; Node *right_child; char letter; } Node; vector<char> stack; void print_paths(Node *root) { if (root == NULL) return; // Add a letter to the current path stack.push_back(root->letter); // If the node is leaf, print out the path in the stack // Assume, that we have print_out_single_path(...) // function implemented somewhere. if (root->left_child == NULL && root->right_child == NULL) print_out_single_path(stack); // Go down to the left child if it exists. if (root->left_child != NULL) print_paths(root->left_child); // Go down to the right child if it exists. if (root->right_child != NULL) print_paths(root->right_child); // Remove the letter from the stack. Since we have printed // out all the paths going through this node so far, // we return control to our parent node. stack.pop(); }

Final stage for me. Time complexity.

So the code above is similar to the one proposed by the Facebook engineer. His reasoning about the complexity was, “The time is O(n), since we visit every node only once.” It seems reasonable, but it does not take into account print_out_single_path function!

One should notice, that the worst case is when we have a full binary tree. Then we call the print function ~\(n/2\) times (!), where n is number of nodes. In a full binary tree the length of a path is actually the height of the tree, hence \(log(n)\). Therefore, the complexity is \(O(n \cdot log(n))\)!

We also require \(O(n)\) of additional space in the worst case (when the tree is one long path).

Takeaways