>

Merge Intervals

"""
56. Merge Intervals

https://leetcode.com/problems/merge-intervals

NOTES
  * A common routine for interval problems is to sort the array of intervals
    by each interval's starting index.
"""


class Solution:
    def merge(self, intervals: list[list[int]]) -> list[list[int]]:
        if not intervals:
            return []
        sorted_intervals = sorted(intervals)
        ans: list[list[int]] = [sorted_intervals[0]]
        # p1 is a pointer into ans. p2 is a pointer into sorted_intervals.
        p1, p2 = 0, 1
        while p2 < len(sorted_intervals):
            if overlap(ans[p1], sorted_intervals[p2]):
                ans[p1] = merge(ans[p1], sorted_intervals[p2])
            else:
                ans.append(sorted_intervals[p2])
                p1 += 1
            p2 += 1
        return ans


def overlap(a: list[int], b: list[int]) -> bool:
    """
    Returns True if `a` and `b` overlap, otherwise returns False.
    """
    return a[0] <= b[1] and b[0] <= a[1]


def merge(a: list[int], b: list[int]) -> list[int]:
    """
    Merges two intervals (`a` and `b`).
    """
    return [min(a[0], b[0]), max(a[1], b[1])]


class OptimizedSolution:
    """
    Since the intervals are already sorted, we only need to check if the end
    index of the last interval is greater than or equal to the start index of
    the current interval.
    """

    def merge(self, intervals: list[list[int]]) -> list[list[int]]:
        intervals.sort(key=lambda x: x[0])
        merged: list[list[int]] = []
        for interval in intervals:
            if not merged or merged[-1][1] < interval[0]:
                merged.append(interval)
            else:
                merged[-1][1] = max(merged[-1][1], interval[1])
        return merged
Source | LeetCode

grind.rip

From Grind Hell, with Love