Insert Interval (Leetcode #57)
The 'Insert Interval' problem is a common interview question that challenges your understanding of arrays and interval management. In this blog post, we'll take a closer look at how to efficiently solve the problem, breaking down both the naive and optimized approaches. By the end of this guide, you'll have a deeper understanding of how to merge overlapping intervals and insert new intervals into a sorted list.
Understanding the Problem Statement
The problem, Leetcode 57: Insert Interval, gives you a list of non-overlapping intervals sorted by their start times and a new interval that you need to insert into the list. The task is to ensure that the final list is non-overlapping and sorted. The new interval might overlap with some of the existing intervals, and the solution should merge any overlapping ones.
Example
Suppose you have the list of intervals [[1, 3], [6, 9]]
and a new interval [2, 5]
. After inserting the new interval and merging any overlapping intervals, the output should be [[1, 5], [6, 9]]
.
Brute Force Approach
A brute force approach to this problem would involve iterating through the entire list of intervals to find where the new interval should be placed, inserting it, and then scanning the entire list again to merge overlapping intervals. This solution requires multiple passes through the list, leading to increased time complexity. Although this approach may be intuitive, it is far from optimal for larger inputs. Specifically, you would:
Insert the new interval in its correct position.
Iterate through the list and merge any overlapping intervals.
Return the final merged list.
This method involves multiple passes through the list and hence results in O(n^2) time complexity in the worst case, which isn't efficient.
Hint to Solve the Problem Efficiently
The key to optimizing the solution is to divide the intervals into three categories:
Intervals that end before the new interval starts (“left”).
Intervals that overlap with the new interval (“merge”).
Intervals that start after the new interval ends (“right”).
By categorizing intervals this way, you can simplify the merging process to just one pass through the list, leading to a much more efficient solution.
Efficient Solution
Let’s dive into the efficient solution provided in the code:
class Solution:
def insert(self, intervals, newInterval) -> List[List[int]]:
left, right = [], []
start, end = newInterval
for i in intervals:
# i ends before new_interval starts
if i[1] < start:
left.append(i)
# i starts after new_interval ends
elif i[0] > end:
right.append(i)
# i overlaps with new_interval
else:
start = min(start, i[0])
end = max(end, i[1])
return left + [[start, end]] + right
Explanation
Initialization: Create two lists,
left
andright
, to store intervals that are clearly not overlapping with the new interval. Extractstart
andend
values fromnewInterval
.Iterating Through Intervals:
For each interval, check if it ends before
newInterval
starts. If so, add it toleft
.If an interval starts after
newInterval
ends, add it toright
.Otherwise, the intervals overlap, and you need to merge them by updating the
start
andend
.
Final Result: Combine the
left
, the merged interval, and theright
intervals to get the final output.
Time and Space Complexity
Time Complexity: The time complexity of this solution is O(n), where
n
is the number of intervals. The solution requires only one pass through the list, and every interval is processed once.Space Complexity: The space complexity is O(n), as we use additional lists (
left
andright
) to store intervals, but these lists are just reordering of the original intervals.
Conclusion
The 'Insert Interval' problem is a great example of how breaking a problem into smaller, manageable parts can lead to a more efficient solution. By categorizing the intervals and only merging when necessary, we achieve a linear-time solution that is both simple and effective. The key takeaway here is to avoid multiple passes through the data whenever possible and instead leverage categorization to streamline operations.
Try implementing this efficient solution on your own, and you’ll be better equipped to tackle similar interval-based problems in coding interviews!