Algorithm Search⌘K

Proofs: Stack with minimum

These are the human proofs of Stack with minimum, at full length.

The stack with minimum returns the least item after each operation full

This proof shows: correctness.

Setting. The structure is a stack SS of pairs. Write its state, from the bottom to the top, as ⟨(x1,m1),…,(xk,mk)⟩\langle (x_1, m_1), \ldots, (x_k, m_k) \rangle with k≥0k \ge 0. The stack that the user sees is ⟨x1,…,xk⟩\langle x_1, \ldots, x_k \rangle. The items come from a set with a total order.

Invariant (M). mj=min⁡{x1,…,xj}m_j = \min\{x_1, \ldots, x_j\} for each 1≤j≤k1 \le j \le k.

We show that each operation keeps (M), that the stack of the xjx_j changes as a stack must, and that each query returns the right value. The underlying stack of pairs meets the stack laws, so a push of a pair adds it at the top and a pop removes and returns the top pair.

Initialization. The new structure is empty, k=0k = 0, and (M) holds with no index to check.

PUSH(S,x)(S, x). Line L1 sets m=xm = x if k=0k = 0, and m=min⁡(x,mk)m = \min(x, m_k) otherwise. Line L2 pushes (x,m)(x, m), so the new state has xk+1=xx_{k+1} = x and mk+1=mm_{k+1} = m, and the pairs below are unchanged. For j≤kj \le k, (M) holds as before. For j=k+1j = k + 1: if k=0k = 0 then m1=x1=min⁡{x1}m_1 = x_1 = \min\{x_1\}. If k≥1k \ge 1 then, by (M) for j=kj = k,

mk+1=min⁡(x,mk)=min⁡(xk+1,min⁡{x1,…,xk})=min⁡{x1,…,xk+1}.m_{k+1} = \min(x, m_k) = \min(x_{k+1}, \min\{x_1, \ldots, x_k\}) = \min\{x_1, \ldots, x_{k+1}\}.

The user's stack is ⟨x1,…,xk,x⟩\langle x_1, \ldots, x_k, x \rangle.

POP(S)(S), k≥1k \ge 1. Line L3 removes the top pair (xk,mk)(x_k, m_k), and line L4 returns xkx_k, the top item of the user's stack. The pairs 1,…,k−11, \ldots, k - 1 are unchanged, so (M) holds for them, and the user's stack is ⟨x1,…,xk−1⟩\langle x_1, \ldots, x_{k-1} \rangle.

TOP(S)(S), k≥1k \ge 1. Line L5 returns xkx_k. Nothing changes.

MIN(S)(S), k≥1k \ge 1. Line L6 returns mkm_k, which by (M) is min⁡{x1,…,xk}\min\{x_1, \ldots, x_k\}, the least item of the user's stack. Nothing changes.

The lean variant. The variant keeps the items in a stack I=⟨x1,…,xk⟩I = \langle x_1, \ldots, x_k \rangle and a second stack QQ that receives xx on a push exactly when QQ is empty or x≤top(Q)x \le \text{top}(Q), and loses its top on a pop exactly when the popped item equals top(Q)\text{top}(Q). Its invariant is: QQ is the sequence of the prefix minima with repeats, that is, of the items xjx_j with xj≤xix_j \le x_i for all i<ji < j, in the order of jj. A push of xx appends xx to this sequence exactly when x≤min⁡{x1,…,xk}=top(Q)x \le \min\{x_1, \ldots, x_k\} = \text{top}(Q), which is the test. On a pop of xkx_k, the item xkx_k is in the sequence exactly when xk≤x_k \le every earlier item. In that case it is the last entry of QQ and equals top(Q)\text{top}(Q). If it is not in the sequence, then some earlier item is less than xkx_k, so top(Q)<xk\text{top}(Q) < x_k and the test fails. So the test removes xkx_k from QQ exactly when it is there, and top(Q)=min⁡{x1,…,xk}\text{top}(Q) = \min\{x_1, \ldots, x_k\} is kept, because the last prefix minimum is the minimum. With the strict test x<top(Q)x < \text{top}(Q) on push, a repeated minimum is not recorded, and the first pop of it removes the only copy from QQ; this is the pitfall of the page. ■\blacksquare

Back to Stack with minimum