Range Minimum Query algorithms
  • OCaml 97.5%
  • Dune 2.5%
Find a file
2023-05-27 18:39:19 +02:00
src add segment tree implementation 2023-05-27 18:28:38 +02:00
tests add segment tree implementation 2023-05-27 18:28:38 +02:00
.gitignore dot files 2023-05-27 12:37:00 +02:00
.ocamlformat dot files 2023-05-27 12:37:00 +02:00
dune-project opam 2023-05-27 13:47:53 +02:00
LICENSE opam 2023-05-27 13:47:53 +02:00
README.md add LCA example in readme 2023-05-27 18:39:19 +02:00
rmq.opam opam 2023-05-27 13:47:53 +02:00

Given a preprocessed array, a Range Minimum Query (RMQ) returns the minimum element in a chosen subarray:

Find the minimum in a subarray

This library provides various implementations with different trade-offs:

Preprocessing and Memory Query
Naive O(1) O(N) No preprocessing
Dense O(N²) O(1) Precompute all queries
Sparse O(N logN) O(1) Precompute queries with a power-of-two length
Hybrid O(N) O(1) Combine Dense and Sparse to shave a log!
Segment O(N) O(logN) Binary partitioning of precomputed queries

benchmarks

Since RMQ is a useful building block for more advanced algorithms, this package exposes a low-level interface returning the index of the minimum element: online documentation

let arr = [| "b" ; "a" ; "d" ; "c" ; "e" ; "a" |] (* given an array *)
let min_array = Rmq.of_array ( <= ) arr (* configure its [min] function *)
module Impl = Rmq.Hybrid (* choose an RMQ implementation *)
let t = Impl.preprocess min_array (* to precompute some answers *)
let found_index = Impl.minimum_index min_array t ~i:2 ~len:3 (* query range [2..4] for its minimum *)
let () = assert (arr.(found_index) = "c")

As an example application, consider finding the Lowest Common Ancestor (LCA) between any two nodes in a tree:

  • An array of nodes is obtained by an in-order traversal of the tree from left to right (in dashed red)
  • The minimum element (by depth) between any two nodes in the array is their lowest common ancestor

LCA

When applied to a suffix tree, this yields a constant time "Longest Common Prefix (LCP)" between any substrings! (with linear preprocessing)