interval overlap
interval search
algorithm
data structures
computational geometry

search for interval overlap in list of intervals?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Interval overlap search appears in scheduling, booking systems, memory allocators, and genomic analysis. The right algorithm depends on whether you need one overlap, all overlaps, or repeated online queries. This article covers practical approaches from simple sorting scans to interval trees.

Defining Overlap Clearly

For half-open intervals represented as (start, end), two intervals overlap when:

  • a.start < b.end
  • b.start < a.end

Using half-open semantics avoids boundary ambiguity for adjacent ranges.

Approach 1: Naive Pairwise Check

For small lists, compare all pairs.

python
1from typing import List, Tuple
2
3Interval = Tuple[int, int]
4
5def find_any_overlap_naive(intervals: List[Interval]):
6    n = len(intervals)
7    for i in range(n):
8        for j in range(i + 1, n):
9            a, b = intervals[i], intervals[j]
10            if a[0] < b[1] and b[0] < a[1]:
11                return (a, b)
12    return None
13
14print(find_any_overlap_naive([(1, 3), (4, 6), (2, 5)]))

Time complexity is quadratic, which becomes expensive as input grows.

Approach 2: Sort by Start and Scan

If you need to detect any overlap efficiently in a static list, sort by start time and scan once.

python
1from typing import List, Tuple
2
3Interval = Tuple[int, int]
4
5def find_any_overlap_sorted(intervals: List[Interval]):
6    if len(intervals) < 2:
7        return None
8
9    items = sorted(intervals, key=lambda x: x[0])
10    prev = items[0]
11
12    for cur in items[1:]:
13        if cur[0] < prev[1]:
14            return (prev, cur)
15        if cur[1] > prev[1]:
16            prev = cur
17    return None
18
19print(find_any_overlap_sorted([(5, 8), (1, 3), (3, 5), (2, 4)]))

Sorting plus linear scan gives O(n log n) time and is usually the best default for one-time checks.

Approach 3: Interval Tree for Repeated Queries

When intervals are queried repeatedly, use an interval tree. Each node stores an interval and the max end value of its subtree, enabling pruning.

python
1class Node:
2    def __init__(self, interval):
3        self.interval = interval
4        self.max_end = interval[1]
5        self.left = None
6        self.right = None
7
8
9def insert(root, interval):
10    if root is None:
11        return Node(interval)
12
13    if interval[0] < root.interval[0]:
14        root.left = insert(root.left, interval)
15    else:
16        root.right = insert(root.right, interval)
17
18    root.max_end = max(root.max_end, interval[1])
19    return root
20
21
22def overlaps(a, b):
23    return a[0] < b[1] and b[0] < a[1]
24
25
26def query_any_overlap(root, target):
27    if root is None:
28        return None
29
30    if overlaps(root.interval, target):
31        return root.interval
32
33    if root.left and root.left.max_end > target[0]:
34        return query_any_overlap(root.left, target)
35
36    return query_any_overlap(root.right, target)

This is useful for calendar systems and stream-like insert plus query workloads.

Returning All Overlaps

If you need all overlapping pairs, you can use sweep-line techniques with event sorting. For large datasets, this is often faster than checking every pair.

For moderate sizes, sorted scan with an active set structure is usually sufficient and easier to maintain than a fully optimized computational geometry implementation.

Choosing the Right Strategy

Use a simple decision rule:

  • Small one-off list: naive approach.
  • Medium or large static list: sort and scan.
  • Many repeated dynamic queries: interval tree.

Choose based on workload shape, not only theoretical complexity.

Common Pitfalls

A common pitfall is inconsistent endpoint semantics. Mixing closed intervals and half-open intervals causes boundary bugs for adjacent ranges.

Another issue is not normalizing invalid intervals where start is greater than end. Validate or swap endpoints before processing.

Developers also forget stable sorting and tie behavior when starts are equal. Define deterministic ordering and overlap policy explicitly.

Finally, using advanced trees for tiny datasets can overcomplicate code without measurable benefit. Start simple and optimize only when profiling shows need.

Summary

  • Define overlap semantics clearly before implementing.
  • Use O(n log n) sort and scan for most static overlap checks.
  • Use interval trees for repeated online overlap queries.
  • Validate interval inputs and boundary rules early.
  • Match algorithm complexity to actual data and query patterns.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.