Given an array of intervals
where intervals[i] = [starti, endi]
, merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.
Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].
Example 2:
Input: intervals = [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considered overlapping.
Constraints:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We want to combine overlapping time periods. The most straightforward way is to look at every possible pair of time periods and see if they overlap, combining them if they do.
Here's how the algorithm would work step-by-step:
def merge_intervals_brute_force(intervals):
intervals_list = intervals[:] # Copy to avoid modifying the original
number_of_intervals = len(intervals_list)
while True:
merged_at_least_once = False
for first_interval_index in range(number_of_intervals):
for second_interval_index in range(first_interval_index + 1, number_of_intervals):
first_interval = intervals_list[first_interval_index]
second_interval = intervals_list[second_interval_index]
# Check if intervals overlap
if (first_interval[0] <= second_interval[1] and first_interval[1] >= second_interval[0]):
# Create merged interval
merged_interval_start = min(first_interval[0], second_interval[0])
merged_interval_end = max(first_interval[1], second_interval[1])
merged_interval = [merged_interval_start, merged_interval_end]
# Replace the first interval with the merged interval
intervals_list[first_interval_index] = merged_interval
# Remove the second interval
del intervals_list[second_interval_index]
number_of_intervals -= 1
merged_at_least_once = True
break # Restart the inner loop
if merged_at_least_once:
break # Restart the outer loop
# No merges occurred, so break
if not merged_at_least_once:
break
return intervals_list
The most efficient way to combine overlapping time periods is to first arrange them in order based on when they start. Then, we go through them one by one, merging them as we go.
Here's how the algorithm would work step-by-step:
def merge_intervals(intervals):
# Sort intervals by start time.
intervals.sort(key=lambda interval: interval[0])
merged_intervals = []
for interval in intervals:
# If the list of merged intervals is empty or if the current
# interval does not overlap with the last interval, append it.
if not merged_intervals or merged_intervals[-1][1] < interval[0]:
merged_intervals.append(interval)
else:
# Otherwise, there is overlap, so we merge the current interval
# with the last one.
merged_intervals[-1][1] = max(merged_intervals[-1][1], interval[1])
return merged_intervals
Case | How to Handle |
---|---|
Null or empty input array | Return an empty array or throw an IllegalArgumentException depending on the requirements. |
Input array with only one interval | Return the input array directly as there's nothing to merge. |
Intervals are already non-overlapping and sorted | The algorithm should still correctly return the original array after sorting (if sorting is part of the solution). |
Intervals are in reverse order and overlapping heavily. | The sorting step will handle reordering, and subsequent merging logic should correctly combine them. |
Intervals with large start and end values (potential for integer overflow if calculating lengths) | Ensure comparisons and calculations avoid overflow, potentially using long data types or careful subtraction. |
Intervals with identical start and end times (e.g., [1, 1], [2, 2]) | The merging logic should treat these as valid intervals and handle them appropriately. |
A very large number of overlapping intervals, potentially impacting performance. | Ensure the sorting algorithm used is efficient (O(n log n)), and the merging process is linear, preventing quadratic time complexity. |
Intervals with start time equal to another interval's end time (e.g., [1, 2], [2, 3]) | The problem description implies these should be merged so this case should result in [1,3]. |