Recursion

Solve a problem by having a function call itself on a smaller version of the same problem until it hits a base case.

Recursion Practice Problems

Easy

3 problems
  1. 105

    Reverse Linked List

    Reverse the order of the nodes in a singly linked list.

    easy
  2. 106

    Merge Two Sorted Lists

    Merge two sorted linked lists into a single sorted linked list.

    easy
  3. 262

    Factorial of a Number

    Compute the factorial of a number using recursion.

    easy

Medium

5 problems
  1. 107

    Pow(x, n)

    Compute x raised to the power n without repeatedly multiplying one step at a time.

    medium
  2. 108

    Unique Binary Search Trees II

    Generate every structurally unique binary search tree that stores values from 1 to n.

    medium
  3. 263

    Validate Binary Search Tree

    Check whether a binary tree satisfies the binary search tree property.

    medium
  4. 264

    Tower of Hanoi

    Find the sequence of moves that solves the Tower of Hanoi puzzle.

    medium
  5. 265

    Flatten a Multilevel Doubly Linked List

    Flatten a linked list where nodes may have a child pointer into a single-level list.

    medium

How to practise recursion

Spotting one

The problem contains a smaller copy of itself. Reversing a list is reversing a shorter list and then attaching one item. Checking a tree is checking two smaller trees.

If you can describe the job in terms of the same job on something smaller, recursion fits.

Two parts, always

Every recursive solution has exactly two pieces, and missing either one is the usual cause of failure.

The stopping case is the smallest version, where you already know the answer without asking again. The shrinking step is how you make the problem smaller before asking again, so you are guaranteed to reach the stopping case.

Where to start

Factorial of a Number is the smallest possible example. It is only useful for seeing the two pieces clearly.

Reverse Linked List and Merge Two Sorted Lists next. Both are short, and both build their answer on the way back out of the recursion rather than on the way in, which is the first genuinely new idea here.

Pow(x, n) introduces halving. To raise a number to the twentieth power, raise it to the tenth and square it. Two calls collapse into one and a slow method becomes a fast one.

Validate Binary Search Tree teaches passing information downward. Each call needs to know the range its values are allowed to sit in, and that range comes from above.

Tower of Hanoi, Flatten a Multilevel Doubly Linked List and Unique Binary Search Trees II are the harder end. The last one builds every possible answer rather than one, which is a real step up.

Common mistakes

A stopping case that can never be reached. Checking for exactly zero while the value drops by two at a time, so it steps straight past.

Calling the function and throwing away the result. A recursive call you do not return or store does nothing at all.

Redoing the same work over and over. If the same small problem keeps turning up, the fix is to remember previous answers, and that is where dynamic programming starts.