Merge Intervals in Python

Merging intervals is a common problem where we combine overlapping intervals in a collection. For example, if we have intervals [[1,3], [2,6], [8,10], [15,18]], the result after merging overlapping intervals would be [[1,6], [8,10], [15,18]] because [1,3] and [2,6] overlap and merge into [1,6].

Algorithm Steps

The approach uses sorting and a stack-based method ?

  • If the interval list is empty, return an empty list
  • Sort intervals by their start time
  • Initialize a stack and add the first interval
  • For each remaining interval:
    • Get the last interval from the stack
    • If intervals overlap (last end ? current start), merge them
    • Otherwise, add the current interval to the stack
  • Return the stack containing merged intervals

Simple Implementation

Here's a clean implementation using Python's built-in sorting ?

def merge_intervals(intervals):
    if not intervals:
        return []
    
    # Sort intervals by start time
    intervals.sort(key=lambda x: x[0])
    
    merged = [intervals[0]]
    
    for current in intervals[1:]:
        last = merged[-1]
        
        # Check if intervals overlap
        if last[1] >= current[0]:
            # Merge intervals
            last[1] = max(last[1], current[1])
        else:
            # No overlap, add current interval
            merged.append(current)
    
    return merged

# Test the function
intervals = [[1,3], [2,6], [8,10], [15,18]]
result = merge_intervals(intervals)
print(result)
[[1, 6], [8, 10], [15, 18]]

Stack-Based Implementation

The original approach using explicit stack operations ?

class Solution:
    def merge(self, intervals):
        if len(intervals) == 0:
            return []
        
        # Sort intervals by start time
        intervals.sort(key=lambda x: x[0])
        
        stack = []
        stack.append(intervals[0])
        
        for i in range(1, len(intervals)):
            last_element = stack[-1]
            
            if last_element[1] >= intervals[i][0]:
                # Merge overlapping intervals
                last_element[1] = max(intervals[i][1], last_element[1])
                stack.pop()
                stack.append(last_element)
            else:
                stack.append(intervals[i])
        
        return stack

# Test the implementation
solution = Solution()
intervals = [[1,3], [2,6], [8,10], [15,18]]
result = solution.merge(intervals)
print(result)
[[1, 6], [8, 10], [15, 18]]

Edge Cases

Let's test with various edge cases ?

def merge_intervals(intervals):
    if not intervals:
        return []
    
    intervals.sort(key=lambda x: x[0])
    merged = [intervals[0]]
    
    for current in intervals[1:]:
        last = merged[-1]
        if last[1] >= current[0]:
            last[1] = max(last[1], current[1])
        else:
            merged.append(current)
    
    return merged

# Test edge cases
test_cases = [
    [[1,4], [4,5]],           # Adjacent intervals
    [[1,4], [2,3]],           # Completely overlapping
    [[1,3], [5,7], [9,12]],   # No overlaps
    [[1,10], [2,6], [8,9]]    # Multiple overlaps
]

for i, intervals in enumerate(test_cases, 1):
    result = merge_intervals(intervals)
    print(f"Test {i}: {intervals} ? {result}")
Test 1: [[1, 4], [4, 5]] ? [[1, 5]]
Test 2: [[1, 4], [2, 3]] ? [[1, 4]]
Test 3: [[1, 3], [5, 7], [9, 12]] ? [[1, 3], [5, 7], [9, 12]]
Test 4: [[1, 10], [2, 6], [8, 9]] ? [[1, 10]]

Time Complexity

The time complexity is O(n log n) due to sorting, where n is the number of intervals. The merging process takes O(n) time, making sorting the dominant factor.

Conclusion

Merging intervals requires sorting by start time and then checking for overlaps. The key insight is that two intervals [a,b] and [c,d] overlap if b ? c when sorted by start time. Use Python's built-in sort for simplicity.

Updated on: 2026-03-25T07:55:31+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements