Program to find intervals by merging target interval in Python

Suppose we have a list of non-overlapping intervals sorted by end time. We need to merge a target interval into this list while maintaining the non-overlapping and sorted properties.

For example, if we have intervals = [[1, 15], [25, 35], [75, 90]] and target = [10, 30], the output will be [[1, 35], [75, 90]] because the target interval [10, 30] overlaps with both [1, 15] and [25, 35], merging them into a single interval [1, 35].

Algorithm

To solve this problem, we follow these steps:

  • Add the target interval to the list of intervals

  • Sort all intervals by their start time

  • Initialize result list with the first interval

  • For each remaining interval:

    • If it overlaps with the last interval in result, merge them

    • Otherwise, add it to the result

Implementation

class Solution:
    def solve(self, intervals, target):
        # Add target interval to the list
        intervals.append(target)
        
        # Sort intervals by start time
        intervals.sort(key=lambda x: x[0])
        
        # Initialize result with first interval
        result = [intervals[0]]
        
        # Process remaining intervals
        for i in range(1, len(intervals)):
            current_interval = intervals[i]
            last_result = result[-1]
            
            # Check if current interval overlaps with last merged interval
            if current_interval[0] <= last_result[1]:
                # Merge intervals by extending the end time
                last_result[1] = max(last_result[1], current_interval[1])
            else:
                # No overlap, add current interval to result
                result.append(current_interval)
        
        return result

# Test the solution
solution = Solution()
intervals = [[1, 15], [25, 35], [75, 90]]
target = [10, 30]

print("Original intervals:", intervals)
print("Target interval:", target)
print("Merged intervals:", solution.solve(intervals.copy(), target))
Original intervals: [[1, 15], [25, 35], [75, 90]]
Target interval: [10, 30]
Merged intervals: [[1, 35], [75, 90]]

How It Works

Let's trace through the example step by step:

def merge_intervals_step_by_step(intervals, target):
    print(f"Step 1: Original intervals: {intervals}")
    print(f"Step 2: Target interval: {target}")
    
    # Add target to intervals
    intervals.append(target)
    print(f"Step 3: After adding target: {intervals}")
    
    # Sort by start time
    intervals.sort(key=lambda x: x[0])
    print(f"Step 4: After sorting: {intervals}")
    
    # Merge overlapping intervals
    result = [intervals[0]]
    print(f"Step 5: Initialize result: {result}")
    
    for i, interval in enumerate(intervals[1:], 1):
        print(f"Step {5+i}: Processing {interval}")
        if interval[0] <= result[-1][1]:
            old_end = result[-1][1]
            result[-1][1] = max(result[-1][1], interval[1])
            print(f"  ? Overlaps! Merge: extend end from {old_end} to {result[-1][1]}")
        else:
            result.append(interval)
            print(f"  ? No overlap, add to result")
        print(f"  ? Current result: {result}")
    
    return result

intervals = [[1, 15], [25, 35], [75, 90]]
target = [10, 30]
final_result = merge_intervals_step_by_step(intervals.copy(), target)
print(f"Final result: {final_result}")
Step 1: Original intervals: [[1, 15], [25, 35], [75, 90]]
Step 2: Target interval: [10, 30]
Step 3: After adding target: [[1, 15], [25, 35], [75, 90], [10, 30]]
Step 4: After sorting: [[1, 15], [10, 30], [25, 35], [75, 90]]
Step 5: Initialize result: [[1, 15]]
Step 6: Processing [10, 30]
  ? Overlaps! Merge: extend end from 15 to 30
  ? Current result: [[1, 30]]
Step 7: Processing [25, 35]
  ? Overlaps! Merge: extend end from 30 to 35
  ? Current result: [[1, 35]]
Step 8: Processing [75, 90]
  ? No overlap, add to result
  ? Current result: [[1, 35], [75, 90]]
Final result: [[1, 35], [75, 90]]

Alternative Approach

Here's a more functional approach using built-in Python functions:

def merge_target_interval(intervals, target):
    # Combine and sort intervals
    all_intervals = sorted(intervals + [target], key=lambda x: x[0])
    
    # Merge overlapping intervals
    merged = []
    for start, end in all_intervals:
        if merged and start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])
    
    return merged

# Test with different examples
test_cases = [
    ([[1, 15], [25, 35], [75, 90]], [10, 30]),
    ([[1, 3], [6, 9]], [2, 5]),
    ([[1, 4], [6, 8]], [10, 12])
]

for intervals, target in test_cases:
    result = merge_target_interval(intervals, target)
    print(f"Intervals: {intervals}, Target: {target} ? Result: {result}")
Intervals: [[1, 15], [25, 35], [75, 90]], Target: [10, 30] ? Result: [[1, 35], [75, 90]]
Intervals: [[1, 3], [6, 9]], Target: [2, 5] ? Result: [[1, 9]]
Intervals: [[1, 4], [6, 8]], Target: [10, 12] ? Result: [[1, 4], [6, 8], [10, 12]]

Conclusion

This algorithm efficiently merges a target interval into a sorted list of non-overlapping intervals. The key insight is to sort all intervals by start time and then merge overlapping intervals in a single pass, maintaining O(n log n) time complexity due to sorting.

Updated on: 2026-03-25T13:43:57+05:30

223 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements