monotonic sequence is a sequence that is either entirely non-increasing or entirely non-decreasing.

Ordered Data Structures Comparison

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) |

Monotonic Queues

A Monotonic Queues is a Queue (on its behaviour, but it is implemented by Deque) that maintains its elements in a monotonic order.

Behaviour

Example: Decreasing Queue

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]
}

Monotonic Stacks

A Monotonic Stack is a Stack that maintains its elements in a monotonic order.

Behaviour

Example: Decreasing Stack