← DSA
MEDIUM

Non-overlapping Intervals

PracticeNeetCode ↗LeetCode ↗

Given an array of intervals, return the minimum number of intervals you'd need to remove so that the rest don't overlap each other.

Example

Input intervals = [[1,2],[2,3],[3,4],[1,3]]
Output 1

Key Pointers

Step-by-Step Analysis

  1. Sort intervals by end time.
  2. Set prev_end to the end of the first interval, and a removal count to 0.
  3. For each following interval, if its start is before prev_end, it overlaps — increment count and keep prev_end as is (the earlier-ending interval stays kept).
  4. Otherwise, there's no overlap — update prev_end to this interval's end.
  5. Return count.

Complexity

Time: O(n log n) for the sort — Space: O(1) extra

Code

def eraseOverlapIntervals(intervals: list[list[int]]) -> int:
    intervals.sort(key=lambda x: x[1])
    count = 0
    prev_end = intervals[0][1]

    for start, end in intervals[1:]:
        if start < prev_end:
            count += 1
        else:
            prev_end = end

    return count

Code Explanation

How the solution above works, piece by piece.

  1. Sort by end. Among overlapping intervals, keeping the one that ends first can never hurt, because it blocks the least future time.
  2. prev_end is the end of the last kept interval.
  3. If the next interval starts before prev_end, it overlaps: remove it (count += 1) and keep prev_end unchanged.
  4. Otherwise keep it and move prev_end to its end.
  5. O(n log n) for the sort.

Visual Walkthrough

Running it on intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]:

Intervals sorted by end with one removed[1,2]keep[2,3]keep[1,3]remove[3,4]keep012345
Sorted by end time. Keeping the interval that ends earliest leaves the most room for the rest. [1, 3] starts before the previous kept end (2), so it overlaps and is removed: 1 removal.
keptremoved

Video Explanation

NeetCode — LeetCode 435