Skip to content
dsa450for five year olds

Stacks & Queues · 14 of 38

Reverse a stack using recursion

Flip a pile of plates upside down using only the pile itself, by taking plates off and sliding each one back in at the bottom.

Simple way
time O(n)
room O(n)
Clever way
time O(n^2)
room O(n)

The problem, simply

You get a stack, a pile where you can only touch the top: push puts something on top, pop takes the top off, peek looks at it, and isEmpty checks if the pile is empty. Reverse it, so the bottom item ends on top.

The catch: no other stack, queue, array or list is allowed. You may only use recursion, functions that call themselves. Their waiting calls are allowed to remember one item each.

A story to remember it

Picture it

stackbefore
1234top
stackafter
4321top

Before: 4 is on top. After: the same pile upside down, with 1 on top.

  • looking now

Examples

Four plates

In
bottom [1, 2, 3, 4] top
Out
bottom [4, 3, 2, 1] top

4 was on top and goes to the bottom. 1 was at the bottom and comes to the top.

Two plates

In
bottom [5, 9] top
Out
bottom [9, 5] top

9 is held, 5 is put down first, then 9 slides under 5.

With repeats

In
bottom [2, 2, 7] top
Out
bottom [7, 2, 2] top

Equal plates still move, but the result looks the same where they sit.

One plate or none

In
bottom [8] top and an empty stack
Out
bottom [8] top and an empty stack

Nothing to flip.

Way 1: the simple way

If any helper box were allowed, this is easy. Pop everything into a queue. The queue now holds the items top first. Push them back in that same order, and the old top ends up at the bottom.

  1. While the stack is not empty, pop and add to the back of a queue.
  2. While the queue is not empty, take from the front and push.
stackstack
empty
queuehelper queue (front ... back)
outin4321frontback

Way 1 halfway: the numbers were popped into a queue in the order 4, 3, 2, 1. Pushing them back in that order puts 1 on top.

  • looking now
java
import java.util.*;

class Solution {
    public void reverse(Deque<Integer> stack) {
        Queue<Integer> line = new ArrayDeque<>();
        while (!stack.isEmpty()) line.offer(stack.pop());   // top comes out first
        while (!line.isEmpty()) stack.push(line.poll());    // and goes back in first, at the bottom
    }
}

How long it takes: every item moves twice, O(n). Extra room: the queue, O(n). Fast, but it breaks the rule: it uses another structure.

Way 2: the clever way

Use two recursive functions.

insertAtBottom(x) puts x under everything:

  1. If the stack is empty, push x. Done.
  2. Otherwise pop the top and hold it, call insertAtBottom(x) on the smaller stack, then push the held item back.

reverse() flips the stack:

  1. If the stack is empty, stop.
  2. Pop the top and hold it, call reverse() on the smaller stack, then insertAtBottom(held).

Why it works: after the inner reverse(), the rest is upside down. The item we held was above all of them, so in the flipped stack it belongs below all of them.

Pop everything, then slide each number under the rest

01 / 14

stackthe stack (bottom ... top)
1234top
stackcall stack
empty

The stack holds 1, 2, 3, 4 with 4 on top. Call reverse().

  • looking now
  • checking
  • done
  • answer
  • path
  • just added
java
import java.util.*;

class Solution {
    public void reverse(Deque<Integer> stack) {
        if (stack.isEmpty()) return;
        int top = stack.pop();           // hold the top plate
        reverse(stack);                  // flip the rest
        insertAtBottom(stack, top);      // the old top belongs at the very bottom
    }

    private void insertAtBottom(Deque<Integer> stack, int x) {
        if (stack.isEmpty()) {
            stack.push(x);               // nothing in the way: x is the bottom
            return;
        }
        int held = stack.pop();          // lift one plate out of the way
        insertAtBottom(stack, x);
        stack.push(held);                // put it back on top
    }
}

How long it takes: reverse runs n times, and the kth insertAtBottom lifts k - 1 plates, so the total is 0 + 1 + ... + (n - 1), about n^2 / 2, which is O(n^2). Extra room: at the deepest point about n calls wait on the call stack, O(n). That is the price of the "no other structure" rule.

Watch out for

  • Pushing the held item back before the inner reverse() call. The stack never gets smaller and the calls never end.
  • Forgetting that the call stack is real memory. A stack of 100,000 items needs 100,000 waiting calls, which can throw StackOverflowError in Java.
  • java.util.Stack works too, but Deque with push and pop is the modern choice. Both put new items on top.

What interviewers ask next

  • Sort a stack with recursion. Same shape, but instead of inserting at the bottom, insert the held item where it belongs in the sorted stack.
  • Insert at the bottom of a stack, by itself. That is insertAtBottom alone, O(n) time and O(n) call stack.
  • Reverse a queue with recursion. Easier: take the front, reverse the rest, then add it at the back. Only O(n), because a queue already lets you add at the far end.
  • Can you reverse a stack in O(n) with no extra structure? If the stack is built as a linked list you own, yes: reverse the arrows of the list. With only push and pop, no.

Remember this

Grown-up words: the plate tower is a stack, the helpers holding plates are frames on the call stack, insertAtBottom is a recursive helper, and "no other box allowed" means no auxiliary data structure.