Search lands in PR-5.1 (Pagefind).

How-to Intermediate

Chapter 3 Updated

Remove Interval

Each interval yields a left remnant, a right remnant, or both.

  • Full 5m
  • Revision 2m
  • Flow 1m

Problem Statement

Given a sorted set of disjoint intervals and an interval to remove, return the remaining intervals after the removal — with overlapping portions carved out.

Input

  • intervals — a sorted list of disjoint intervals.
  • toBeRemoved — a single interval [start, end] to carve out.
Example input
intervals   = [[0,2],[3,4],[5,7]]
toBeRemoved = [1,6]

Output

The remaining intervals in sorted order, after toBeRemoved has been erased from each overlapping interval.

Expected output
[[0,1],[6,7]]

Constraints

  • 1 ≤ intervals.length ≤ 10⁴
  • -10⁹ ≤ startᵢ < endᵢ ≤ 10⁹
  • intervals is sorted by startᵢ.
  • toBeRemoved.length == 2.

Intuition

Walk through each interval once. For each one, ask: does it overlap the removal range?

  • No overlap → keep it unchanged.
  • Overlap → keep whatever sits outside the removal zone: a left remnant and/or a right remnant.

Every original interval produces 0, 1, or 2 output intervals.

Left and right remnants
Interval:     [══════════════════════]
Remove:              [════════════]
Left part:    [══════]                       ← kept if s < rm_s
Right part:                        [══════]  ← kept if e > rm_e

Solution

remove_interval.py
def removeInterval(intervals, toBeRemoved):
    result = []
    rm_s, rm_e = toBeRemoved
 
    for s, e in intervals:
        if e <= rm_s or s >= rm_e:
            result.append([s, e])       # no overlap
        else:
            if s < rm_s:
                result.append([s, rm_s])  # left remnant
            if e > rm_e:
                result.append([rm_e, e])  # right remnant
 
    return result

Complexity

MetricValueReason
TimeO(n)Single pass — no sorting needed since input is sorted
SpaceO(n)Output array (each interval yields 0, 1, or 2 remnants)

Edge Case Thinking

ScenarioHandling
Removal range outside all intervalsEvery interval falls into the “no overlap” branch → output equals input.
Removal range covers every intervalEvery interval is fully swallowed → result = [].
Removal strictly inside one intervalThat interval splits into two remnants (left + right).
Touching endpoint s == rm_e or e == rm_ss >= rm_e / e <= rm_s is true → keep as-is (half-open semantics).
Empty intervalsReturn [].

Comments

Comments are disabled in this environment. Set PUBLIC_GISCUS_REPO, PUBLIC_GISCUS_REPO_ID, and PUBLIC_GISCUS_CATEGORY_ID to enable.