Reviewed by Aditya Kumar · Last reviewed 2026-03-24
To merge overlapping intervals efficiently, first sort the intervals by their start times. Then, iterate through the sorted list, merging intervals that overlap with the last merged interval. This…
This easy-level Python/Coding question appears frequently in data engineering interviews at companies like Microsoft. While less common, it tests deeper understanding that distinguishes strong candidates.
Start by clearly defining the core concept being asked about. Interviewers want to see that you understand the fundamentals before diving into implementation details. Structure your answer with a definition, then explain the practical application with a concise example. The expert answer includes a code example that demonstrates the implementation pattern.
To merge overlapping intervals efficiently, first sort the intervals by their start times. Then, iterate through the sorted list, merging intervals that overlap with the last merged interval. This approach yields a time complexity of O(N log N) due to the sorting step, and O(N) space complexity in the worst case for the result.
The core principle is that sorting by start time guarantees that any potential overlap for the current interval must occur with an interval that has already been processed or is the next in the sorted sequence. After initializing a result list with the first interval, we iterate through the remaining intervals:
Example:
Input: [[1,3], [2,6], [8,10], [15,18]]
[[1,3], [2,6], [8,10], [15,18]] (already sorted)merged = [[1,3]][2,6]: 2 <= 3 (overlap). Update merged[-1] to [1, max(3,6)] = [1,6]. merged = [[1,6]][8,10]: 8 > 6 (no overlap). Append [8,10]. merged = [[1,6], [8,10]][15,18]: 15 > 10 (no overlap). Append [15,18]. merged = [[1,6], [8,10], [15,18]][[1,6], [8,10], [15,18]]
def merge_intervals(intervals):
if not intervals:
return []
intervals.sort(key=lambda x: x[0]) # Sort by start time
merged = [intervals[0]]
for current_start, current_end in intervals[1:]:
last_merged_end = merged[-1][1]
if current_start <= last_merged_end: # Overlap
merged[-1][1] = max(last_merged_end, current_end)
else: # No overlap
merged.append([current_start, current_end])
return merged
In a production data engineering context, this pattern is highly relevant for tasks like consolidating time windows (e.g., event logs, sensor data validity periods, or sessionization) or merging data ranges within a data warehouse. For extremely large datasets that don't fit in memory, the sorting step becomes the primary challenge. Distributed processing frameworks like Apache Spark would require a distributed sort (e.g., using sortBy or sortByKey, which involves shuffles across partitions) before a linear scan can be performed. If intervals are already naturally grouped by a key (e.g., customer ID or device ID), then merging can occur independently within each group after a groupBy operation, significantly reducing the global sorting overhead.
In the interview, also mention handling edge cases like an empty input list or a list with a single interval.
Pro-Move: In-place merge. Red Flag: O(n²) comparison.
Some links below are affiliate links. If you buy through them we may earn a small commission at no extra cost to you — it helps keep DataEngPrep free.
According to DataEngPrep.tech, this is one of the most frequently asked Python/Coding interview questions, reported at 1 company. DataEngPrep.tech maintains an editor-reviewed database of 1,863 data engineering interview questions across 7 categories.