Stack, Queue, Heap
Notes and typical questions for Stack, Queue or Heap related problems
Notes
When performing stack-like operations on a
String, using aStringBuilderis often simpler and more efficient than using an explicit stack data structure.Although sliding windows questions are usually related to the 2-pointer solution. If the sliding windows question needs to compare numbers within the window, you also need to consider the solution: 2-pointer + monotonic queue.
PruorityQueue
poll(): Remove the head item
In Java,
ArrayDequeis faster thanLinkedListexcept for removing elements. Reference:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist
Typical Questions (37)
Mutual implementation between Queue and Stack (2)
LC 232. Implement Queue using Stacks
# Analysis on amortized O(1) TC for pop # Assumption: When stack2 is empty, get pop calls for all items in the queue first pop: O(2*n) transfer + O(1) pop other pops: (n - 1) * O(1) → O(n - 1) ------------------------------- Total operations overall n pop calls: 2*n+1+n-1 = 3*n Amortized TC for pop: (3*n)/n ≈ O(1)
🟠 LC 225. Implement Stack using Queues
Approach 1: Use 1 queue. Straightforward
👍 1.1 Push O(n), Pop O(1)
1.2 Push O(1), Pop O(n). Not preferred compared to 1.1.
Approach 2: Use 2 queues
2.1 Push O(n), Pop O(1): NOT straightforward, queue1 is to store all elements in stack order with the help of queue2
2.2 Push O(1), Pop O(n). Not preferred compared to 2.1.
Normal Stack Common Use Cases (8)
Notes
Common cases
Matching / Pairing: resolve parentheses or symbols
Adjacent Merge / Reduction: repeatedly merge/remove neighbors based on a rule
Expression Evaluation: operators, precedence, calculators
Nested Structure Parsing: decode nested patterns
State Backtracking: undo previous state (path/string)
LC 20. Valid Parentheses
The most elegant way is to push
) or ] or ]when get( or [ or {. This way can simplifyif/elselogicOptimal Answer. TC: O(n), SC: O(n)
LC 1047. Remove All Adjacent Duplicates In String
Approach 1: Use a stack, the most straightforward way
👍 Approach 2: Use 2 pointers, this way is better due to no space usage for the stack
⚪ LC 1209. Remove All Adjacent Duplicates in String II
Optimal Answer. TC: O(n), SC: O(n)
LC 150. Evaluate Reverse Polish Notation
⚪ LC 71. Simplify Path
Optimal Answer. TC: O(n), SC: O(n)
LC 735. Asteroid Collision
Optimal Answer. TC: O(n), SC: O(n)
🌟 🔴 LC 394. Decode String
It's very hard to implement. I check the solution directly. Go through this test case "3[a2[c]2[d]]" to understand why the solution works...
TC: O(max(k)∗n), where max(k) is the max value of
k,nis the size of the string array.SC: O(n).
🟠 LC 224. Basic Calculator
It's similar to the above LC 394 question.
Hints
Try to resolve it using 1 stack.
Store signs ('+', '-') using an
int varinstead of a stack.
Try to handle numbers in the input string that have more than 1 digit without using a
whileloop
I finally made it by myself (I already saw the solution in previous rounds)!
Optimal Answer. TC: O(n), SC: O(n)
🟠 LC 227. Basic Calculator II
Although it does not have
(), but it's more complicated than LC 224 due to*/Optimal Answer. TC: O(n), SC: O(1)
🟠 LC 1249. Minimum Remove to Make Valid Parentheses
Approach 1
I came up with this approach independently before checking the LeetCode editorial. The core idea is similar to the solution for LC 224 (Basic Calculator).
Answer. TC: O(n2), SC: O(n).
For TC, it's slow due to repeated string copying when merging nested builders. Conceptually, the process resembles:
b1.append(b2.append(...append(bk)...));where deeply nested parentheses cause the same characters to be copied multiple times.
👍 Approach 2: Optimal Answer. TC: O(n), SC: O(n)
LC 2197. Replace Non-Coprime Numbers in Array
Optimal Answer. TC: O(nlogMax), SC: O(n)
Normal Queue Common Use Cases (3)
LC 933. Number of Recent Calls
Optimal Answer. TC: O(n), SC: O(n)
⚪ LC 649. Dota2 Senate
The solution with 2 queues is more clear and simpler.
Optimal Answer. TC: O(n), SC: O(n)
LC 346. Moving Average from Data Stream
Optimal Answer. TC: O(1), SC: O(n)
⚪ LC 362. Design Hit Counter
At first, I used binary search in
getHits()and didn't remove anything in the queue because I didn't realize thatgetHits()is called with timestamps in increasing order as well.Optimal Answer.
TC: Both
hit()andgetHits(): amortized O(1)SC: O(1). Max 300 items in the queue.
Monotonic Queue (1)
🔴 LC 239. Sliding Window Maximum
Optimal Solution. TC: O(n), SC: O(k)
Monotonic Stack (11)
Use case: For an element in an array, when you need to find the index/value of the 1st element to the left/right that is greater/smaller than it.
Basic requirements for 1st Element:
Example: Find the next greater element in elements after the current element.
Use a monotonic stack to maintain indices in an increasing or decreasing order (order is determined by the value of indexes) based on the requirement.
Complex requirements for 1st Element:
Example: Find the smallest element larger than the current element in the elements after it.
Steps
Create another array storing the index of the original array and preprocessing it by sorting indices based on values of the original array and secondary by indices to ensure order.
Traverse sorted indices and use a stack to handle the 1st element condition.
Basic Monotonic Stack Problems
🌟 LC 739. Daily Temperatures
Optimal Answer. TC: O(n), SC: O(n)
⚪ LC 496. Next Greater Element I
Optimal Answer. TC: O(n), SC: O(n)
🟠 LC 503. Next Greater Element II
Solve the circular problem by iterating the array twice.
In round 3, I somehow tried to use the remaining items in the stack to solve the circular problem, but that's NOT the correct way.
Optimal Answer. TC: O(n), SC: O(n)
🟠 LC 901. Online Stock Span
TC: Amortized O(1)
SC: O(n)
⚪ LC 155. Min Stack
You can do the implementation with the
Stackdata structure.Try to do it using only 1 stack.
Optimal Answer. TC: O(1) for each operation. SC: O(n)
Trapping Rain Water Problems
🌟 LC 42. Trapping Rain Water
⚪ Approach 1 with a stack
Accumulate the result by calculating the trapped water horizontally
When
height[i] == stack.peekLast(), there are two valid approaches:Allow duplicate items in the stack: Push the current
height[i]into the stack as usual.Keep only unique items in the stack: First, remove the older duplicate from the stack. Then, push the new
height[i]into the stack. Reason: The new item can serve as the left boundary for the next rectangle, whereas the older duplicate is no longer useful.
Optimal Solution. TC: O(n), SC: O(n)
🟠 Approach 2 with 2 pointers
Accumulate the result by calculating the trapped water vertically
Optimal Answer. TC: O(n), SC: O(1)
Largest Rectangle Problem
🌟 🔴 LC 84. Largest Rectangle in Histogram
It's a reversed version of LC 42.
It's easy to make mistakes when getting the width of the rectangle.
Optimal Answer. TC: O(n), SC: O(n)
🔴 LC 85. Maximal Rectangle
It's a genius solution based on LC 84 above
Optimal Solution. TC: O(m∗n), SC: O(n)
Advanced Monotonic Stack Problems
🌟 🔴 LC 962. Maximum Width Ramp
This problem can also be resolved by 2 pointers +
rightMaxarray (see that section). It's necessary to grasp this approach as well.The monotonic stack is used for storing starting points. Need another array iteration from the end of the array to check valid results
Optimal Solution. TC: O(n), SC: O(n)
🌟 🔴 LC 2863. Maximum Length of Semi-Decreasing Subarrays
This question is the same as LC 962
Approach 1: Monotonix Stack. TC: O(n), SC: O(n)
Approach 2: 2 pointers +
rightMinarray. TC: O(n), SC: O(n)
🔴 LC 975. Odd Even Jump
This solution is based on DP + Monotonic Stack and this question can also be solved by DP + TreeMap
Optimal Solution. TC: O(n∗logn), SC: O(n)
Monotonic Deque (1)
🔴 LC 3420. Count Non-Decreasing Subarrays After K Operations
This question is super hard and even the solution is very hard to understand. Add some comments in the optimal answer and go through some examples to get the idea.
I'm still not sure why reversing the array is more efficient.
Optimal Answer. TC: O(n), SC: O(n)
Max/Min Heap Common Use Cases (11)
Notes
Whenever you see that you need to choose the k smallest or the k largest among a group of numbers always consider using a heap(priority queue).
🌟 LC 347. Top K Frequent Elements
Learn how to initialize
PriorityQueuewith a customComparatorMinHeap Answer: TC O(n∗logk), SC: O(n+k)
🌟 LC 215. Kth Largest Element in an Array
MinHeap Solution. TC: O(n∗logk), SC: O(k)
TC: O(n+m), where n is the length of
numsand m ismaxValue - minValueSC: O(m), m is
maxValue - minValue
🟠 LC 2336. Smallest Number in Infinite Set
n is the number
addBack(num)and m is the number ofpopSmallest()method calls.TC: O((m+n)∗logn)
SC: O(n)
🔴 LC 2542. Maximum Subsequence Score
Idea
k-1 largest numbers of
nums2will never be selected. For the selected number fromnums2in each possible score combination, it can only be the kth largest number or all other numbers which < kth largest number innums2For each possible score combination, the questions have 2 requirements (1 for
nums1, 1 fornums2). It's impossible to consider both 2 requirements at the same time. Therefore, we need to fix 1 requirement first and sort out another requirement at the same time. Since we know the specific enumeration of the selected numbers in nums2, we can first fix the chosen numbers from nums2. Then, we can dynamically select the numbers from nums1 using aminHeap.
Optimal Answer. TC: O(n∗logn). SC: O(n)
🟠 LC 2462. Total Cost to Hire K Workers
Very easy to make mistakes during implementation.
For the sake of brevity, let m be the given integer candidates
TC: O((k+m)∗logm)
SC: O(m)
🌟 🟠 LC 253. Meeting Rooms II
Optimal Answer. TC: O(n∗logn), SC: O(n)
🟠 LC 2402. Meeting Rooms III
TC: O(M∗logM+M∗logN)
For inner
whileloop, It will have a maximum ofNiterations each time, but it can't haveNiterations every time. We can't pop more items than we have previously pushed, and we only push one 1 item per outer loop. Since we only pushMtimes, we can only popM-1times over the whole function duration.
SC: O(N)
⚪ LC 3318. Find X-Sum of All K-Long Subarrays I
The idea is straightforward and just implementation is kind of long...
TC: O(n∗k∗logx)
SC: O(k+x)
⚪ LC 1509. Minimum Difference Between Largest and Smallest Value in Three Moves
Approach 1: Full sorting + check result
Approach 2 (better): Partial sorting using heap + check result
Optimal Solution. TC: O(n), SC: O(1)
🌟 ⚪ LC 295. Find Median from Data Stream
Optimal Answer. TC: O(logn), SC: O(n)
🌟 LC 23. Merge k Sorted Lists
Approach 2 is better, but its implementation is trickier.
Approach 1 using Heap: Optimal Answer.
Let N be the total number of nodes and K be the number of lists
TC: O(N∗logK), SC: O(K)
Approach 2 using Divide & Conquer: Optimal Answer. TC: O(N∗logK), SC: O(1)
🔴 LC 502. IPO
I came up with a solution that gets TLE. The problem is that I rebuilt the “feasible set” from scratch each round when choosing projects.
Optimal Answer. TC: O(n∗logn), SC: O(n)
🟠 LC 373. Find K Pairs with Smallest Sums
Optimal Answer. TC: O(k∗logk), SC: O(k)
🌟 🔴 LC 407. Trapping Rain Water II
Optimal Answer. TC: O(m∗n∗log(m∗n)), SC: O(m∗n)
⚪ LC 2163. Minimum Difference in Sums After Removal of Elements
Optimal Answer. TC: O(n∗logn), SC: O(n)
Last updated