AlgoMaster Logo

Minimum Interval to Include Each Query

Last Updated: April 2, 2026

hard
4 min read

Understanding the Problem

We have a set of intervals on the number line, and for each query point, we need to find the smallest interval that contains that point. "Contains" means the point falls between the interval's left and right endpoints (inclusive), and "smallest" means the interval with the minimum size (right - left + 1).

The challenge is efficiency. With up to 100,000 intervals and 100,000 queries, checking every interval for every query would be way too slow. We need a strategy that avoids redundant work, and the key insight is that sorting, both the intervals and the queries, lets us process everything in a single sweep instead of brute-forcing each query independently.

Key Constraints:

  • 1 <= intervals.length <= 10^5 → With n up to 100,000 intervals, O(n^2) is 10^10 operations, far too slow. We need O(n log n) or better per dimension.
  • 1 <= queries.length <= 10^5 → Same scale as intervals. The combined work must stay near O((n + q) log(n + q)).
  • 1 <= left_i <= right_i <= 10^7 → Large value range rules out direct indexing over the number line. We must work with event points, not with every possible integer.

Approach 1: Brute Force

Intuition

The most direct approach: for each query, scan every interval and check if it contains the query point. Among all intervals that do, pick the one with the smallest size.

This is what you would naturally write first, and it gives us a correct baseline to optimize from.

Algorithm

  1. Create a result array of size queries.length.
  2. For each query q at index j:
    1. Initialize minSize = infinity.
    2. For each interval [left, right]: if left <= q <= right, compute size = right - left + 1 and update minSize.
    3. If minSize is still infinity, set result[j] = -1. Otherwise, set result[j] = minSize.
  3. Return result.

Example Walkthrough

Let's trace through intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5]:

Code

For every single query, we scan through all n intervals. Many intervals share similar left endpoints. If we sorted intervals and queries, we could avoid re-scanning intervals we've already ruled out. What if we processed queries in sorted order and kept a running set of active intervals?

Approach 2: Sorting + Min-Heap (Line Sweep)

Intuition

Here's the key insight: if we sort both the intervals (by left endpoint) and the queries (by value), we can sweep from left to right across the number line. For each query, we add all intervals whose left endpoint is at or before the query. These are candidates, intervals that start early enough to possibly contain the query. But some of them end before the query point, so we need to discard those.

We want the smallest valid interval at any moment. A min-heap keyed by interval size gives us exactly that. We push candidate intervals onto the heap, lazily pop any whose right endpoint is less than the current query, and the heap's top is our answer.

Algorithm

  1. Sort intervals by left endpoint.
  2. Create a list of (query_value, original_index) pairs and sort by query_value.
  3. Initialize a min-heap keyed by interval size and a pointer i = 0 into the sorted intervals.
  4. For each query (q, idx) in sorted order:
    1. Push all intervals where left <= q onto the heap as (size, right).
    2. Pop all entries from the heap where right < q.
    3. If the heap is non-empty, result[idx] = heap.top().size. Otherwise, result[idx] = -1.
  5. Return result.

Example Walkthrough

1Sorted intervals. Sorted queries: [(2,0),(3,1),(4,2),(5,3)]. Process q=2.
0
push
[1,4]
1
[2,4]
push
2
[3,6]
3
[4,4]
1/5

Code

The heap approach works well, but when queries contain many duplicates, we're doing repeated heap operations for the same query value. What if we computed the answer once per unique query value and reused it?

Approach 3: Sorting + Hash Map (Optimal)

Intuition

This approach takes the same sweep idea but makes it cleaner. Instead of pairing every query with its original index and sorting those pairs, we extract the unique query values, compute the answer for each one, and store results in a hash map. At the end, we just look up each original query's answer.

The sweep logic is identical: sort intervals by left endpoint, process unique queries in sorted order, use a min-heap to track the smallest active interval. But the code is shorter and, when queries have duplicates, we avoid redundant heap operations.

Algorithm

  1. Sort intervals by left endpoint.
  2. Extract sorted unique query values.
  3. Initialize a min-heap keyed by interval size and an interval pointer i = 0.
  4. For each unique query value q in sorted order:
    1. Push all intervals where left <= q onto the heap as (size, right).
    2. Pop all entries where right < q.
    3. Store queryMap[q] = heap.top().size (or -1 if empty).
  5. Build the result array by looking up each original query in queryMap.

Example Walkthrough

1Sorted intervals. Unique queries: [2, 5, 19, 22]. Process q=2.
0
push
[1,8]
1
[2,3]
push
2
[2,5]
push
3
[20,25]
1/5

Code