Hello! Welcome to the final lesson in our course on Data Structures and Algorithms.
In our last lesson, we explored the greedy paradigm by solving the Activity Selection and Fractional Knapsack problems. A key takeaway was how a simple preprocessing step—sorting the input based on a specific property (like finish times or value-to-weight ratios)—can unlock a simple and efficient solution.
Today, we'll build directly on that idea to tackle one of the most common problem patterns in technical interviews. Your learning outcome for this lesson is to solve problems involving merging overlapping intervals. This is a fundamental greedy algorithm problem, and mastering it will equip you to solve a wide range of related questions.
1. Understanding the "Merge Intervals" Problem
The problem is straightforward: you are given a collection of intervals, where each interval is represented by a start and an end point. Your task is to merge all the intervals that overlap and return a new list of non-overlapping intervals that cover all the original ranges.
For example, given [[1,3], [2,6], [8,10], [15,18]]:
[1,3]and[2,6]overlap. They merge to become[1,6].- The other intervals,
[8,10]and[15,18], do not overlap with[1,6]or each other. - The final result is
[[1,6], [8,10], [15,18]].
An important edge case to consider is when intervals touch at their boundaries, for example, [1,4] and [4,5]. These are also considered overlapping and should be merged into [1,5].
2. The Core Strategy: Sort and Scan
If you try to merge intervals in their given, arbitrary order, the logic can become very complex. You might have to compare every interval with every other interval, leading to an inefficient O(n²) solution.
However, just like in our previous lesson, sorting simplifies everything. If we sort the intervals based on their start times, any potentially overlapping intervals will be adjacent in the sorted list. This allows us to process them in a single, linear scan.
To build a strong intuition for this, let's watch a short video that visualizes the power of sorting.
Merge Intervals - Sorting - Leetcode 56
This video from NeetCode provides an excellent visual intuition for the problem. It clearly demonstrates how sorting brings order to the chaos.
Watch from the beginning to 05:39. Pay close attention to the number line visualization. See how messy the intervals are initially and how sorting by their start time makes it obvious which ones are candidates for merging.
3. The Merging Algorithm
After sorting, the greedy algorithm is elegant and simple:
- Sort the intervals based on their start times.
- Create a
mergedlist and initialize it with the first interval from the sorted list. - Iterate through the rest of the sorted intervals, from the second one onwards.
- For each
currentinterval, look at thelastinterval in yourmergedlist. - Check for overlap: If the
currentinterval's start is less than or equal to thelastinterval's end (current.start <= last.end), they overlap.- Merge: Update the
lastinterval's end to be the maximum of the two end points:last.end = max(last.end, current.end). This extends the merged interval to cover both.
- Merge: Update the
- No overlap: If they don't overlap, it means the
currentinterval starts a new, non-overlapping block. Simply add it to themergedlist. - After the loop finishes, the
mergedlist contains the final result.
This visual from w3resource perfectly captures the process:

For a more detailed breakdown of this single-scan approach and its Java implementation, the following article is an excellent guide.
Now that we have the strategy, let's dive into the implementation details. The 'EnjoyAlgorithms' article explains the optimized 'sorting and single scan' approach, which is the standard solution you'll be expected to know.
Read the sections titled 'Using the sorting and single scan' and its corresponding 'Time and space complexity analysis'. Focus on the step-by-step logic and the provided Java code, which represents a clean and efficient solution.
4. A Complete Java Implementation
Since your focus is on practical implementation for interviews, let's analyze a complete, runnable Java solution. This will help solidify your understanding of how to use Arrays.sort with a custom comparator and how to manage the results in an ArrayList.
DSA Merge Intervals: Explanation & Solution
This article from w3resource provides a full Java class for merging intervals, complete with a main method for testing. It's a great practical example to study.
Please read the following sections: Start with 'Java - Merge Intervals' to see the complete code, including test cases and output. Then, review the 'Linear Scan Approach...' section, which provides pseudocode and reinforces the logic. Finally, read the 'Time and Space Complexity' analysis. This will consolidate all the concepts into a single, practical package.
The key line in the Java implementation is the sort:Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
This uses a lambda expression to define a comparator on the fly, sorting the 2D array intervals based on the first element ([0]) of each inner array. This is a common and concise pattern in modern Java that you should be very comfortable with.
Test your understanding!
Given the intervals [[1,4], [0,2], [3,5], [8,10]], what is the merged output? Walk through the steps.
Show answer
-
Sort by start time:
[[0,2], [1,4], [3,5], [8,10]] -
Initialize
mergedlist:merged = [[0,2]] -
Process
[1,4]:lastinterval inmergedis[0,2].currentinterval is[1,4].- Check for overlap:
1 <= 2? Yes. - Merge: Update
last's end.mergedbecomes[[0, max(2, 4)]], which is[[0,4]].
-
Process
[3,5]:lastinterval inmergedis now[0,4].currentinterval is[3,5].- Check for overlap:
3 <= 4? Yes. - Merge: Update
last's end.mergedbecomes[[0, max(4, 5)]], which is[[0,5]].
-
Process
[8,10]:lastinterval inmergedis[0,5].currentinterval is[8,10].- Check for overlap:
8 <= 5? No. - Add
currenttomerged.mergedis now[[0,5], [8,10]].
-
Final Result:
[[0,5], [8,10]].
5. Common Variations and Interview Follow-ups
In an interview, after you solve the main problem, you'll often be asked about variations. Here are two very common ones:
a) Non-overlapping Intervals (LeetCode 435)
- Problem: Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
- Connection: This is the inverse of a problem you've already solved: the Activity Selection Problem! The greedy approach here is to find the maximum number of non-overlapping intervals you can keep. The minimum number to remove is simply
total intervals - max non-overlapping intervals. - Greedy Strategy: To find the maximum set of non-overlapping intervals, you sort by end time, not start time. This is a crucial distinction.
L8. Non Overlapping Intervals | Greedy Algorithms Playlist
This problem is a fantastic example of how a slight change in the goal can change the greedy strategy. This video from 'take U forward' explains the logic.
Watch from 02:21 to 07:29. Notice how the problem is reframed as finding the maximum number of non-overlapping activities (meetings) and how the strategy shifts to sorting by end times. This should feel very familiar from our last lesson.
b) Meeting Rooms II (LeetCode 253)
- Problem: Given an array of meeting time intervals, find the minimum number of conference rooms required.
- Insight: This is equivalent to finding the maximum number of intervals that are overlapping at any single point in time. This requires a slightly different but related technique, often involving sorting start and end times in separate arrays and using a two-pointer approach, or using a min-heap to track meeting end times. I encourage you to explore this problem on your own as excellent practice.
Conclusion
Congratulations on completing the final lesson! Today, you mastered the "Merge Intervals" problem, a cornerstone of algorithm interviews.
Key Takeaways:
- The most effective strategy for interval problems is almost always to sort the intervals first. For merging, sorting by start time is key.
- The greedy merging algorithm involves a single linear scan after sorting, giving it a time complexity of O(n log n) (dominated by the sort) and a space complexity of O(n) for the result (or O(1) if sorting is in-place and results can be stored in the input array).
- Be aware of common variations, such as finding the minimum removals (Activity Selection pattern, sort by end time) or finding maximum overlaps (Meeting Rooms pattern).
This lesson marks the end of our structured curriculum. You have systematically rebuilt your foundation in Data Structures and Algorithms, from basic collections to advanced topics like Dynamic Programming and Greedy algorithms. The key now is consistent practice. Use the skills you've developed to solve problems on platforms like LeetCode and HackerRank. The "Suggested coding questions to practice" in the EnjoyAlgorithms article is a great place to start.
Best of luck in your technical interviews and competitive programming journey! You have built a strong foundation for success.