Stacks are everywhere — your browser's back button, function call management, undo/redo. Learn how they work and how to use them to solve problems.
A stack is a Last In, First Out (LIFO) data structure. The last element added is the first one removed — like a stack of plates.
class Stack {
private List<Integer> data;
public Stack() {
data = new ArrayList<>();
}
public void push(int val) {
data.add(val); // O(1)
}
public int pop() {
return data.remove(data.size() - 1); // O(1)
}
public int peek() {
return data.get(data.size() - 1); // O(1) — look without removing
}
public boolean isEmpty() {
return data.isEmpty();
}
public int size() {
return data.size();
}
}In Java, you can use the built-in Stack class, or more preferably, Deque implementations like ArrayDeque which provide push() and pop() methods.
Every function call pushes a frame, every return pops it:
main() calls foo()
foo() calls bar()
Stack: [main | foo | bar] ← bar is executing
bar returns → Stack: [main | foo]
foo returns → Stack: [main]
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char ch : s.toCharArray()) {
if (ch == '(' || ch == '{' || ch == '[') {
stack.push(ch);
} else if (ch == ')' || ch == '}' || ch == ']') {
if (stack.isEmpty()) return false;
char top = stack.pop();
if ((ch == ')' &&
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if ("+-*/".contains(token)) {
int b = stack.pop();
int a = stack.pop();
switch (token) {
case "+": stack.push(a + b); break;
case "-": stack.push(a - b); break;
case "*": stack.push(a * b); break
public int[] nextGreater(int[] arr) {
int[] result = new int[arr.length];
Arrays.fill(result, -1);
Stack<Integer> stack = new Stack<>(); // stores indices
for (int i = 0; i < arr.length; i++) {
while (!stack.isEmpty() && arr[stack.peek()] < arr[i]) {
int idx = stack.pop();
result[idx] = arr[i]; // arr[i] is the next greater for idx
}
stack.push(i);
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack; // tracks minimums
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
int minVal = minStack.isEmpty() ? val : Math.min(val, minStack.peek());
minStack.push(minVal);
}
public void pop() {
stack.
| Stack | Queue | |
|---|---|---|
| Order | LIFO — last in, first out | FIFO — first in, first out |
| Add | push to top | enqueue to back |
| Remove | pop from top | dequeue from front |
| Use case | DFS, undo, call stack | BFS, task scheduling |