08. Stack#
Problems at a glance#
| LC | Problem | |
|---|---|---|
| 225 | Implement Stack using Queues | ↗ |
| 20 | Valid Parentheses | ↗ |
| 227 | Basic Calculator II | ↗ |
| 150 | Evaluate Reverse Polish Notation | ↗ |
| 503 | Next Greater Element II | ↗ |
| 739 | Daily Temperatures | ↗ |
| 1762 | Buildings With an Ocean View | ↗ |
| 456 | 132 Pattern | ↗ |
| 735 | Asteroid Collision | ↗ |
| 155 | Min Stack | ↗ |
| 224 | Basic Calculator | ↗ |
| 42 | Trapping Rain Water | ↗ |
| 84 | Largest Rectangle in Histogram | ↗ |
| 1944 | Number of Visible People in a Queue | ↗ |
Problem 1: Implement Stack using Queues (Leetcode:225)#
Problem Statement
Implement a last-in-first-out (LIFO) stack using only two queues. The implemented stack should support all the functions of a normal stack (push, top, pop, and empty).
Implement the MyStack class:
void push(int x)Pushes element x to the top of the stack.int pop()Removes the element on the top of the stack and returns it.int top()Returns the element on the top of the stack.boolean empty()Returnstrueif the stack is empty,falseotherwise.
Notes:
-
You must use only standard operations of a queue, which means that only
push to back,peek/pop from front,sizeandis emptyoperations are valid. -
Depending on your language, the queue may not be supported natively. You may simulate a queue using a list or deque (double-ended queue) as long as you use only a queue's standard operations.
Example 1:
Input:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output:
[null, null, null, 2, 2, false]
Explanation:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2); myStack.top(); // return 2
myStack.pop(); // return 2
myStack.empty(); // return False
Constraints:
1 <= x <= 9- At most
100calls will be made topush,pop,top, andempty.- All the calls to
popandtopare valid.
Follow-up: Can you implement the stack using only one queue?
Code and Explanation
- Keep two queues;
q1always holds the stack contents with the newest element at the front (queue head). - On
push(x): appendxto emptyq2, then dequeue every element fromq1intoq2, then swap the queue references. - After rotation, the most recently pushed value sits at the front of
q1, sopop/topare O(1) queue operations. emptychecks whetherq1has any elements.
Time: push O(n), pop/top/empty O(1) | Space: O(n)
- Use a single queue and maintain LIFO order by rotating after every push.
- Append the new value to the back, then move
size - 1elements from front to back. - The front of the queue always holds the stack top, so
popandtopread from the front. - This satisfies the follow-up of implementing a stack with one queue only.
Time: push O(n), pop/top/empty O(1) | Space: O(n)
Problem 2: Valid Parentheses (Leetcode:20)#
Problem Statement
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Every close bracket has a corresponding open bracket of the same type.
Example 1:
Input: s = "()"
Output: true
Example 2:
Input: s = "()[]{}"
Output: true
Example 3:
Input: s = "(]"
Output: false
Example 4:
Input: s = "([])"
Output: true
Example 5:
Input: s = "([)]"
Output: false
Constraints:
1 <= s.length <= 104sconsists of parentheses only'()[]{}'.
Code and Explanation
- Use a stack to store unmatched opening brackets in order of appearance.
- Map each closing bracket to its required opening partner.
- On a closing bracket, pop the stack and verify the types match; an empty stack means no partner.
- After scanning, validity requires the stack to be empty (all brackets closed).
Time: O(n) | Space: O(n)
- Repeatedly remove every adjacent valid pair
(),[], or{}from the string. - Valid nesting always reduces to empty string after all inner pairs are eliminated.
- If any characters remain, some bracket was unmatched or out of order.
- Simple brute-force alternative; no explicit stack, but models the same LIFO cancellation idea.
Time: O(n²) worst case | Space: O(n)
Problem 3: Basic Calculator II(Leetcode:227)#
Problem Statement
Given a string s which represents an expression, evaluate this expression and return its value.
The integer division should truncate toward zero.
You may assume that the given expression is always valid. All intermediate results will be in the range of [-231, 231 - 1].
Note:
You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().
Example 1:
Input: s = "3+2*2"
Output: 7
Example 2:
Input: s = " 3/2 "
Output: 1
Example 3:
Input: s = " 3+5 / 2 "
Output: 5
Constraints:
1 <= s.length <= 3 * 10^5sconsists of integers and operators('+', '-', '*', '/')separated by some number of spaces.srepresents a valid expression.- All the integers in the expression are non-negative integers in the range
[0, 231 - 1].- The answer is guaranteed to fit in a 32-bit integer.
Code and Explanation
- Defer addition/subtraction by pushing signed terms onto a stack.
- When reading
*or/, immediately combine with the previous stack top (higher precedence). - Each number is fully parsed before applying the operator that preceded it.
- Final answer is the sum of all stack entries — only addition remains.
Time: O(n) | Space: O(n)
- Track a running total (
res) and the last evaluated term (prev). - On
+/-, flushprevintoresand start a new signed term. - On
*//, updateprevin place without touchingres. - Same operator-precedence logic as the stack approach, but uses O(1) extra space.
Time: O(n) | Space: O(1)
Problem 4: Evaluate Reverse Polish Notation (Leetcode:150)#
Problem Statement
You are given an array of strings tokens that represents an arithmetic expression in a Reverse Polish Notation.
Evaluate the expression. Return an integer that represents the value of the expression.
Note that:
- The valid operators are
'+','-','*', and'/'. - Each operand may be an integer or another expression.
- The division between two integers always truncates toward zero.
- There will not be any division by zero.
- The input represents a valid arithmetic expression in a reverse polish notation.
- The answer and all the intermediate calculations can be represented in a 32-bit integer.
Example 1:
Input: tokens = ["2","1","+","3","*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9
Example 2:
Input: tokens = ["4","13","5","/","+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6
Example 3:
Input: tokens = ["10","6","9","3","+","-11","","/","","17","+","5","+"]
Output: 22
Explanation: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
Constraints:
1 <= tokens.length <= 104tokens[i]is either an operator:"+","-","*", or"/", or an integer in the range[-200, 200].
Code and Explanation
- Scan tokens left to right — the natural evaluation order for postfix notation.
- Push operands onto the stack.
- On an operator, pop two operands (second popped is the left operand), compute, push result.
- A valid expression ends with exactly one value on the stack.
Time: O(n) | Space: O(n)
- Parse from the last token recursively — postfix trees are evaluated bottom-up from the right.
- Each operator recursively evaluates its right subtree first, then its left subtree.
- Returns both the computed value and the next index to process.
- Same logic as the stack, expressed as recursion instead of an explicit stack.
Time: O(n) | Space: O(n) recursion depth
Problem 5: Next Greater Element II (Leetcode:503)#
Problem Statement
Given a circular integer array nums (i.e., the next element of nums[nums.length - 1] is nums[0]), return the next greater number for every element in nums.
The next greater number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, return -1 for this number.
Example 1:
Input: nums = [1,2,1]
Output: [2,-1,2]
Explanation: The first 1's next greater number is 2;
The number 2 can't find next greater number.
The second 1's next greater number needs to search circularly, which is also 2.
Example 2:
Input: nums = [2,1,3,4,3]
Output: [3,3,4,-1,4]
Constraints:
1 <= nums.length <= 104-109 <= nums[i] <= 109
Code and Explanation
- Simulate a circular array by iterating
2 * ntimes with indexi % n. - Maintain a monotonic decreasing stack of indices waiting for a greater element.
- When a larger value appears, pop and assign it as the next greater for those indices.
- Only push indices during the first pass (
i < n) to avoid duplicate processing.
Time: O(n) | Space: O(n)
- For each index, scan forward circularly up to
n - 1steps. - The first element strictly greater than
nums[i]is the answer. - If no greater element exists in the full circle, leave
-1. - Straightforward brute force; easy to reason about but slower on large inputs.
Time: O(n²) | Space: O(1) excluding output
Problem 6: Daily Temperatures (Leetcode:739)#
Problem Statement
Given an array of integers temperatures represents the daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the ith day to get a warmer temperature. If there is no future day for which this is possible, keep answer[i] == 0 instead.
Example 1:
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
Example 2:
Input: temperatures = [30,40,50,60]
Output: [1,1,1,0]
Example 3:
Input: temperatures = [30,60,90]
Output: [1,1,0]
Constraints:
1 <= temperatures.length <= 10530 <= temperatures[i] <= 100
Code and Explanation
- Stack stores indices of days still waiting for a warmer day.
- When a warmer temperature arrives, pop all colder days and set their wait distance.
- Push the current index; colder days stay on the stack for future resolution.
- Classic monotonic stack — each index is pushed and popped at most once.
Time: O(n) | Space: O(n)
- For each day, scan every future day until a warmer one is found.
- Record the index difference as the wait time.
- If the inner loop finishes without finding warmth,
res[i]stays 0. - Brute-force baseline that makes the monotonic stack optimization clear.
Time: O(n²) | Space: O(1) excluding output
Problem 7: Buildings With an Ocean View (Leetcode:1762)#
Problem Statement
There are n buildings in a line. You are given an integer array heights of size n that represents the heights of the buildings in the line.
The ocean is to the right of the buildings. A building has an ocean view if the building can see the ocean without obstruction. Formally, a building has an ocean view if all the buildings to its right have a smaller height.
Return a list of indices (0-indexed) of buildings that have an ocean view, sorted in increasing order.
Example 1:
Input: heights = [4,2,3,1]
Output: [0,2,3]
Explanation: Building 1 (0-indexed) does not have an ocean view because building 2 is taller.
Example 2:
Input: heights = [1,3,2,4]
Output: [3]
Explanation: Only building 3 has an ocean view.
Constraints:
1 <= n == heights.length <= 10^51 <= heights[i] <= 10^9
Code and Explanation
- Scan from right to left, tracking the tallest building seen so far (
max_right). - A building has an ocean view iff its height exceeds everything to its right.
- Collect qualifying indices, then reverse to return ascending order.
- One pass, no explicit stack — but uses the same "pop shorter elements" intuition.
Time: O(n) | Space: O(n) for output
- Scan left to right with a monotonic decreasing stack of candidate indices.
- When a taller building appears, pop all shorter buildings — they are blocked from the ocean.
- Remaining stack indices are exactly those with no taller building to their right.
- Stack order is already increasing, matching the required output format.
Time: O(n) | Space: O(n)
Problem 8: 132 Pattern (Leetcode:456)#
Problem Statement
Given an array of n integers nums, a 132 pattern is a subsequence of three integers nums[i], nums[j] and nums[k] such that i < j < k and nums[i] < nums[k] < nums[j].
Return true if there is a 132 pattern in nums, otherwise, return false.
Example 1:
Input: nums = [1,2,3,4]
Output: false
Explanation: There is no 132 pattern in the sequence.
Example 2:
Input: nums = [3,1,4,2]
Output: true
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
Example 3:
Input: nums = [-1,3,2,0]
Output: true
Explanation: There are three 132 patterns in the sequence: [-1, 3, 2], [-1, 3, 0] and [-1, 2, 0].
Constraints:
n == nums.length1 <= n <= 2 * 105-109 <= nums[i] <= 109
Code and Explanation
- Scan right to left;
secondholds the largest validnums[k]seen so far (middle of a 132). - Stack stores decreasing candidates for
nums[j]. - When
nums[i]is less thansecond, we foundi < j < kwithnums[i] < nums[k] < nums[j]. - Values popped from the stack become better
secondcandidates because they sit to the right of a larger peak.
Time: O(n) | Space: O(n)
- Fix the middle index
jand enumerate everyk > j. - The smallest value left of
jis the best candidate fornums[i]. - Check whether any
nums[k]satisfiesnums[i] < nums[k] < nums[j]. - Brute-force triple search; correct but quadratic time.
Time: O(n²) | Space: O(1)
Problem 9: Asteroid Collision (Leetcode:735)#
Problem Statement
We are given an array asteroids of integers representing asteroids in a row. The indices of the asteriod in the array represent their relative position in space.
For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed.
Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet.
Example 1:
Input: asteroids = [5,10,-5]
Output: [5,10]
Explanation: The 10 and -5 collide resulting in 10. The 5 and 10 never collide.
Example 2:
Input: asteroids = [8,-8]
Output: []
Explanation: The 8 and -8 collide exploding each other.
Example 3:
Input: asteroids = [10,2,-5]
Output: [10]
Explanation: The 2 and -5 collide resulting in -5. The 10 and -5 collide resulting in 10.
Constraints:
2 <= asteroids.length <= 104-1000 <= asteroids[i] <= 1000asteroids[i] != 0
Code and Explanation
- Process asteroids left to right; the stack holds survivors so far.
- Collisions only happen when a right-moving asteroid meets a left-moving one (
+then-). - Compare sizes: smaller explodes; equal sizes destroy both; larger right-mover keeps colliding.
- If the current asteroid survives all collisions, push it onto the stack.
Time: O(n) | Space: O(n)
- Recursive helper resolves one incoming asteroid against the current survivors.
- Same collision rules: only
+/-pairs interact; smaller or equal explodes. - If the left-moving asteroid wins, recursively check against the next stack top.
- Equivalent logic to the iterative stack, expressed recursively.
Time: O(n) | Space: O(n) recursion depth
Problem 10: Min Stack (Leetcode:155)#
Problem Statement
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Implement the MinStack class:
MinStack()initializes the stack object.void push(int val)pushes the elementvalonto the stack.void pop()removes the element on the top of the stack.int top()gets the top element of the stack.int getMin()retrieves the minimum element in the stack.
You must implement a solution with O(1) time complexity for each function.
Example 1:
Input ["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
Output
[null,null,null,null,-3,null,0,-2]
Explanation
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); // return -3
minStack.pop();
minStack.top(); // return 0
minStack.getMin(); // return -2
Constraints:
-231 <= val <= 231 - 1- Methods
pop,topandgetMinoperations will always be called on non-empty stacks.- At most
3 * 104calls will be made topush,pop,top, andgetMin.
Code and Explanation
- Maintain two stacks: one for all values, one mirroring the current minimum.
- Push to
min_stackonly when the new value is<=the current minimum (handles duplicates). - On pop, also pop from
min_stackif the removed value equals the current min. getMinreads the top ofmin_stackin O(1).
Time: O(1) per operation | Space: O(n)
- Store each entry as a
(value, min_so_far)tuple on a single stack. - On push,
min_so_faris the smaller of the new value and the previous minimum. - Pop and top operate on the combined tuple — no second stack needed.
- Trades slightly more memory per entry for simpler bookkeeping.
Time: O(1) per operation | Space: O(n)
Problem 11: Basic Calculator (Leetcode:224)#
Problem Statement
Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().
Example 1:
Input: s = "1 + 1"
Output: 2
Example 2:
Input: s = " 2-1 + 2 "
Output: 3
Example 3:
Input: s = "(1+(4+5+2)-3)+(6+8)"
Output: 23
Constraints:
1 <= s.length <= 3 * 105sconsists of digits,'+','-','(',')', and' '.srepresents a valid expression.'+'is not used as a unary operation (i.e.,"+1"and"+(2 + 3)"is invalid).'-'could be used as a unary operation (i.e.,"-1"and"-(2 + 3)"is valid).- There will be no two consecutive operators in the input.
- Every number and running calculation will fit in a signed 32-bit integer.
Code and Explanation
- Track running result, current number, and current sign (+1 or -1).
- On
(, push the accumulated result and sign onto the stack, then reset for the subexpression. - On
), finalize the subexpression, multiply by the saved sign, and add to the saved result. - Stack handles nested parentheses by saving outer context at each open paren.
Time: O(n) | Space: O(n)
- Recursive helper evaluates a subexpression starting at index
i. - On
(, recurse into the nested expression and use its result as the current number. - On
), return the subexpression result and the closing index to the caller. - Same semantics as the stack approach; recursion replaces explicit context saving.
Time: O(n) | Space: O(n) recursion depth
Problem 12: Trapping Rain Water (Leetcode:42)#
Problem Statement
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Example 1:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
Example 2:
Input: height = [4,2,0,3,2,5]
Output: 9
Constraints:
n == height.length1 <= n <= 2 * 1040 <= height[i] <= 105
Code and Explanation
- Monotonic decreasing stack stores indices of bars forming a "basin wall."
- When a taller bar appears, the popped bar is the bottom of a trapped pool.
- Water height =
min(left_wall, right_wall) - bottom; width spans between wall indices. - Each index is pushed and popped once — classic monotonic stack for area accumulation.
Time: O(n) | Space: O(n)
- Precompute the tallest bar to the left and right of every index.
- Water at index
i=min(left_max[i], right_max[i]) - height[i]. - No stack needed — two prefix/suffix passes plus one accumulation pass.
- Alternative O(n) approach; useful when monotonic stack logic is harder to visualize.
Time: O(n) | Space: O(n)
Problem 13: Largest Rectangle in Histogram (Leetcode:84)#
Problem Statement
Given an array of integers heights representing the histogram's bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram.
Example 1:
Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.
Example 2:
Input: heights = [2,4]
Output: 4
Constraints:
1 <= heights.length <= 1050 <= heights[i] <= 104
Code and Explanation
- Append a sentinel
0to force all remaining bars to be processed. - Monotonic increasing stack tracks indices of bars that can extend rightward.
- When a shorter bar appears, pop and compute area using the popped height and span to the new top.
- Width extends from the new stack top (exclusive) to the current index (exclusive).
Time: O(n) | Space: O(n)
- Fix a left boundary
iand expand rightward to everyj >= i. - Track the minimum height in the range
[i, j]— that is the rectangle height. - Width is
j - i + 1; update the global maximum area. - Brute-force baseline highlighting why the monotonic stack achieves O(n).
Time: O(n²) | Space: O(1)
Problem 14: Number of Visible People in a Queue(Leetcode:1944)#
Problem Statement
There are n people standing in a queue, and they numbered from 0 to n - 1 in left to right order. You are given an array heights of distinct integers where heights[i] represents the height of the ith person.
A person can see another person to their right in the queue if everybody in between is shorter than both of them. More formally, the ith person can see the jth person if i < j and min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1]).
Return an array answer of length n where answer[i] is the number of people the ith person can see to their right in the queue.
Example 1:
Input: heights = [10,6,8,5,11,9]
Output: [3,1,2,1,1,0]
Explanation:
Person 0 can see person 1, 2, and 4.
Person 1 can see person 2.
Person 2 can see person 3 and 4.
Person 3 can see person 4.
Person 4 can see person 5.
Person 5 can see no one since nobody is to the right of them.
Example 2:
Input: heights = [5,1,2,3,10]
Output: [4,1,1,1,0]
Constraints:
n == heights.length1 <= n <= 1051 <= heights[i] <= 105- All the values of
heightsare unique.
Code and Explanation
- Scan right to left; stack holds people to the right that person
imight see. - Pop everyone shorter than person
i— each popped person is directly visible. - If anyone remains on the stack, person
ican see exactly one taller person (then view is blocked). - Monotonic decreasing stack counts visible people in O(n).
Time: O(n) | Space: O(n)
- For each person
i, scan every personjto their right. - Track the maximum height strictly between
iandj. - Increment count when both endpoints are taller than everyone in between.
- Direct simulation of the problem definition; O(n²) but easy to verify correctness.
Time: O(n²) | Space: O(1) excluding output



