Python 3.11+
The examples use standard Python containers and syntax available in the supported browser runtime; Interval itself is taught as an interview abstraction.
Verify in Python docs(opens in a new tab)Start-end pair representing a range for overlap, scheduling, and sweep-line problems. This guide turns that contract into deliberate Python operations, interview invariants, and a runnable practice loop.
Recognize it when
Consider Interval when the prompt's constraints and required operations match this shape: Start-end pair representing a range for overlap, scheduling, and sweep-line problems.

Sign in to save your code and progress across devices. The lesson and problem statement remain public.
An interval is a start/end pair plus a boundary convention. Overlap cannot be decided until the contract says whether endpoints are closed, open, or half-open.
Closed [start, end] intervals include both endpoints, so [1, 3] and [3, 5] touch and overlap at
3. Half-open [start, end) intervals make adjacent ranges non-overlapping. Write the comparison from
that rule instead of memorizing < versus <=.
Sort by start, then keep one merged frontier. If the next start is no greater than the frontier end, extend the end; otherwise the frontier is final. Sorting dominates at O(n log n), and copying output avoids mutating caller-owned interval lists.
def normalize_closed_intervals(intervals):
merged = []
for start, end in sorted((start, end) for start, end in intervals):
if not merged or start > merged[-1][1]:
merged.append([start, end])
else:
merged[-1][1] = max(merged[-1][1], end)
return mergedImplement normalize_closed_intervals(intervals). Sort copies and merge overlap or touching boundaries without mutating input.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
When existing intervals are already sorted and disjoint, copy intervals strictly before the new range, merge every touching range, then append the untouched suffix. This is O(n) without re-sorting.
def insert_closed(intervals, new_interval):
result = []
index = 0
start, end = new_interval
while index < len(intervals) and intervals[index][1] < start:
result.append(intervals[index].copy())
index += 1
while index < len(intervals) and intervals[index][0] <= end:
start = min(start, intervals[index][0])
end = max(end, intervals[index][1])
index += 1
result.append([start, end])
result.extend(interval.copy() for interval in intervals[index:])
return resultImplement insert_closed(intervals, new_interval). Existing closed intervals are sorted and disjoint; return the merged insertion in O(n).
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
Use interval merging when ranges themselves are the output. Use start/end events for maximum overlap, room counts, or time-varying state; event tie order must reflect closed versus half-open semantics. Use a difference array when the coordinate domain is small and dense.
State endpoint semantics first, then define what the merged frontier covers. Explain why sorted start order proves no finalized interval can overlap a later one.
Normalize Closed Intervals(opens in a new tab) practices the frontier; Merge Intervals(opens in a new tab) requires recognizing that normalization pattern.
Python 3.11+
The examples use standard Python containers and syntax available in the supported browser runtime; Interval itself is taught as an interview abstraction.
Verify in Python docs(opens in a new tab)Interview bounds depend on the stated representation, input model, and real Python operations.
| Operation | Average | Worst | Interview note |
|---|---|---|---|
| Core Interval workflow | O(n log n) | O(n log n) | Sort copied intervals by start and maintain one merged frontier, extending it whenever the next closed interval starts at or before the frontier end. |
O(n) for the demonstrated Interval workflow.
These are the mistakes most likely to survive a happy-path example and fail a boundary case.
Placeholder code cannot preserve the Interval invariant or satisfy the public contract.
Prevent it: Implement the smallest complete transition and run the public tests before adding optimizations.
Avoid
def normalize_closed_intervals(intervals):
passUse instead
def normalize_closed_intervals(intervals):
ordered = sorted([list(interval) for interval in intervals])
merged = []
for start, end in ordered:
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedWhere you will hit this: Normalize Closed Intervals(opens in a new tab)
Uses a strict comparison and therefore fails to merge intervals that share a closed endpoint.
Prevent it: Keep this invariant visible while editing: State the precise Interval invariant before coding and preserve it after every update, traversal step, or recursive return.
Avoid
def normalize_closed_intervals(intervals):
merged = []
for start, end in sorted(intervals):
if merged and start < merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedUse instead
def normalize_closed_intervals(intervals):
ordered = sorted([list(interval) for interval in intervals])
merged = []
for start, end in ordered:
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedWhere you will hit this: Normalize Closed Intervals(opens in a new tab)
Handle empty state, duplicate values, aliasing, and serialization boundaries explicitly in tests.
Prevent it: Account for every slice, copy, sort, membership test, and container mutation before claiming O(n log n).
Avoid
def normalize_closed_intervals(intervals):
merged = []
for start, end in sorted(intervals):
if merged and start < merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedUse instead
def normalize_closed_intervals(intervals):
ordered = sorted([list(interval) for interval in intervals])
merged = []
for start, end in ordered:
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedWhere you will hit this: Merge Intervals(opens in a new tab)
Official Python documentation supports language behavior. Canonical problem pages provide additional practice context.
python-docs · checked 2026-07-27