A monotonic sequence is a sequence that is either entirely non-increasing or entirely non-decreasing.
| Sorted Array | Binary Search Tree (BST) | Heap | Monotonic Queue | Monotonic Stack | |
|---|---|---|---|---|---|
| Purpose | Searching and Sorting applications | Find global min or max |
UseCase: Dijkstra, Top-K, Scheduling | Track min or max in a sliding window: The values in Queue are changed when the window slides.
****UseCase: Sliding Window Max/Min | Track previous/next smaller or larger element
UseCase: Histogram Area, Stock Span, Next Greater Element | | Data Order Maintained | Monotonic | Tree in-order | Heap order | Monotonic
To maintain monotonic, improve time complexity, and reflect the window range, stale and unrelated values will be removed. | Monotonic |
| Push Time Complexity | O(n)
O(1) (push end)
Push + shifting | O(log n ~ n)
Binary Search | O(log n)
Push + Percolate Up | Amortized O(1)
Push + removing
Stale and unrelated values will be removed. | Amortized O(1)
Push + removing |
| Pop Time Complexity | O(n)
O(1) (pop end/top)
Pop + shifting | O(log n ~ n)
Pop root + connect nodes | O(log n)
Pop index 0 + Percolate Down | O(1)
Pop index 0
Only stale value will be removed. | O(1)
Pop index len-1 |
| Random removal? | ✅
O(n) | ✅
O(log n ~ n)
| ⚠️
Lazy removal (with a map) | ❌ | ❌ |
| Peek Min/Max Time Complexity | O(1)
Return index 0 or len-1 | O(log n ~ n)
Return the leftest or the rightest leaf node. | O(1)
Return index 0 | O(1)
Return index 0 | O(1)
Return index len-1 |
| Space Complexity | O(n) | O(n) | O(n) | O(n) | O(n) |
A Monotonic Queues is a Queue (on its behaviour, but it is implemented by Deque) that maintains its elements in a monotonic order.
Peek method)Peek method)O(1)
k (k is number of elements smaller than n in the stack). But in a sequence, deleted elements in the queue won’t appear again, so the time complexity is amortized to ****O(1).O(1)type DecrQueue struct {
data []int
}
func (mq *DecrQueue) Push(n int) {
for len(mq.data) > 0 && mq.data[len(mq.data)-1] < n {
mq.data = mq.data[:len(mq.data)-1]
}
mq.data = append(mq.data, n)
}
func (mq *DecrQueue) Pop(n int) {
if len(mq.data) > 0 && mq.data[0] == n {
mq.data = mq.data[1:]
}
}
func (mq *DecrQueue) Peek() int {
return mq.data[0]
}
A Monotonic Stack is a Stack that maintains its elements in a monotonic order.