What does a recursion interview question actually test, beyond knowing the syntax?
Three things, and none of them is the syntax. First, can you find the base case, the smallest input where the answer is known without further work. Second, can you shrink the problem so that each recursive call is strictly smaller, which is what guarantees termination. Third, can you keep the state that has to travel with the call, whether that is an accumulator, a path, or a set of used items.
def flatten(nested):
output = []
for item in nested:
if isinstance(item, list):
output.extend(flatten(item))
else:
output.append(item)
return output
print(flatten([1, [2, [3, [4]]], 5]))The output is 1, 2, 3, 4, 5. The function flattens an arbitrarily nested list, and it works because each nested list is strictly smaller than the list that contains it, so the recursion is guaranteed to bottom out.
The mechanism is that a recursive call does two things: it frames a smaller version of the same question, and it combines the answers. The first part is where the base case matters, because without it the recursion never stops. The second part is where the interesting work happens, and that is usually a single line such as an append, a sum or a max.
The trade-off to name is that recursion costs more than a loop in constant factors and it puts the call stack depth in your complexity analysis. A recursion of depth n needs O of n stack space, so a naive recursive solution to a problem with n of the order of a hundred thousand will overflow the stack. Interviewers are watching for whether you notice the exponential trap as well, since a naive recursive solution that recomputes the same subproblems can be far worse than the loop version it replaces.