Solving the Min-Stack Problem in O(1) Time
By: Oluwadamilare Olusakin
Tags: Coding, Programming, Ruby, Algorithms, Interview

Problem Statement and Solution

Create a stack that contains the standard push and pop methods. It should also contain another method min that returns the minimum number in the stack. For extra credit: All operations should take O(1) time.

Let’s get to it.

First, we define our node class like so:

This node class is the most fundamental part of this data structure — be careful with it.

Next, we set up the stack class. Finally!

Notice that unlike the deque, we are only initializing the first node(the top of the stack).

Next, we set up our pushFront method. Pay attention to this method and the stuff we write in it. I will break it down a bit.

In the first line, we create a new node that has a value of number and its next node is our previous first node. We then assign this node as our new first node.

Next, we assign the first node to the @min variable, and we do the same for the @max variable (but only if these variables didn’t exist before).

Next, if the min and max existed before, meaning the stack isn’t empty, we compare the number to the return value of min? and max? . If the number is smaller than @min , we update the min variable to a new node whose value is the smaller number and whose next node is the previous node carrying the previous minimum. We do the same for @max if the number is greater than the previous max.

Next, let’s take a look under the hood at what our min? and max? methods are doing:

We see that the min? method simply returns the value of the minimum variable if it exists.

The max? method returns the value stored in our maximum variable. Note that both operations are constant time: O(1).

I’m sure you are wondering why we haven’t talked about removing data from the stack, but let’s get two more simple methods out of the way before we deal with the more technical popFront.

Next, we may want to ask if our stack is empty. We can do this by checking if the first element has some value:

Next, we may want to peek at the value on top of our stack since it’s basically all we can see:

Finally, the method we’ve all been waiting for! popFront . In a regular stack, all that’s necessary is updating the @first . But now, we have a little more to think about because we also need to keep track of the maximum and minimum values. I have simplified it a little. Take a look at this illustration:

We see that when we popped the top of the stack on the left, we also popped the minimum value. But we see that in the stack on the right the minimum value abandoned its ship and updated to the next minimum in the stack. Since they were connected by nodes, it was as easy as updating the pointers. I’m not certain, but I bet this is how Captain Jack Sparrow eluded his demise so many times in the “Pirates of the Caribbean.”

Here’s the implementation:

We check if the @min or @max are up for eviction. If they are, we quickly allow them to escape into the next available vessel before we pop their previous form, and then we return the value of the node we just deleted.

Note: We only update the min or max value if they are up for eviction, i.e., they are the nodes about to be popped off the top. They simply jump ship until there is nowhere left to run and hide, Jack Sparrow style!