Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 90

Merging Overlapping Intervals

Recommended resources

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:

  1. Sort the intervals based on their start times.
  2. Create a merged list and initialize it with the first interval from the sorted list.
  3. Iterate through the rest of the sorted intervals, from the second one onwards.
  4. For each current interval, look at the last interval in your merged list.
  5. Check for overlap: If the current interval's start is less than or equal to the last interval's end (current.start <= last.end), they overlap.
    • Merge: Update the last interval'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.
  6. No overlap: If they don't overlap, it means the current interval starts a new, non-overlapping block. Simply add it to the merged list.
  7. After the loop finishes, the merged list contains the final result.

This visual from w3resource perfectly captures the process:

Merge Intervals Algorithm Visualization
This image shows the step-by-step merging process. After sorting, the algorithm iterates through the intervals, comparing the current interval with the last merged one and either extending the merge or starting a new one.

For a more detailed breakdown of this single-scan approach and its Java implementation, the following article is an excellent guide.

Merge Overlapping Intervals

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
  1. Sort by start time:
    [[0,2], [1,4], [3,5], [8,10]]

  2. Initialize merged list:
    merged = [[0,2]]

  3. Process [1,4]:

    • last interval in merged is [0,2].
    • current interval is [1,4].
    • Check for overlap: 1 <= 2? Yes.
    • Merge: Update last's end. merged becomes [[0, max(2, 4)]], which is [[0,4]].
  4. Process [3,5]:

    • last interval in merged is now [0,4].
    • current interval is [3,5].
    • Check for overlap: 3 <= 4? Yes.
    • Merge: Update last's end. merged becomes [[0, max(4, 5)]], which is [[0,5]].
  5. Process [8,10]:

    • last interval in merged is [0,5].
    • current interval is [8,10].
    • Check for overlap: 8 <= 5? No.
    • Add current to merged. merged is now [[0,5], [8,10]].
  6. 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.