Min Stack

Problem

Simulate a stack of integers. Commands: push X, pop, top and min. Print one line per command. push prints ok. pop prints the removed value, top prints the top value and min prints the smallest value in the stack. If the stack is empty, pop, top and min print empty. min must work in O(1).

Constraints

  • 1 <= commands <= 10^5

Examples

Input

push 5
push 3
min
pop
min

Output

ok
ok
3
3
5

Solutions

Best approachTime O(1) per commandSpace O(n)

Scanning the stack for the minimum costs O(n) for every min command. A second stack that stores the minimum at each level gives O(1) for all operations.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process commands line by line.
 * Input   : Several lines of commands.
 * Output  : One result line per command.
 * Approach: A stack with a helper stack.
 * Time    : O(1) per command
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: One stack keeps the values. A second stack keeps the smallest value seen up to each level.
        static class MinStack {
            private final java.util.ArrayDeque<Long> values = new java.util.ArrayDeque<>();
            private final java.util.ArrayDeque<Long> minimums = new java.util.ArrayDeque<>();

            void push(long value) {
                values.push(value);
                // Step 2: The new minimum is the smaller of the new value and the old minimum.
                if (minimums.isEmpty() || value < minimums.peek()) {
                    minimums.push(value);
                } else {
                    minimums.push(minimums.peek());
                }
            }

            long pop() {
                minimums.pop();
                return values.pop();
            }

            long top() {
                return values.peek();
            }

            long min() {
                return minimums.peek();
            }

            boolean isEmpty() {
                return values.isEmpty();
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        MinStack stack = new MinStack();
        String[] output = new String[lines.length];
        for (int i = 0; i < lines.length; i++) {
            String[] parts = lines[i].split(" ");

            // Step 3: Run the command. Push always works. The other commands need a non-empty stack.
            if (parts[0].equals("push")) {
                stack.push(Long.parseLong(parts[1]));
                output[i] = "ok";
            } else if (stack.isEmpty()) {
                output[i] = "empty";
            } else if (parts[0].equals("pop")) {
                output[i] = String.valueOf(stack.pop());
            } else if (parts[0].equals("top")) {
                output[i] = String.valueOf(stack.top());
            } else {
                output[i] = String.valueOf(stack.min());
            }
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (1)
  1. Where do you keep the minimum so you do not need to scan?