Non Overlapping Intervals - JS Solution

JS
Editorial

Solution explanation

Solution explanation

Approach

We are given a list of intervals, and some of them may overlap. Our goal is to remove the minimum number of intervals so that no two remaining intervals overlap.

The key insight is that removing the fewest intervals can be achieved by greedily keeping the earliest-finishing non-overlapping intervals. Each early finisher leaves the most room for future intervals, so by always choosing the interval that ends first among those compatible with previous choices, we ensure the minimum number of removals overall.

High-Level Strategy

  1. Step 1: Sort by end time.
    To apply the greedy strategy of keeping the earliest-finishing intervals, we first sort all intervals in ascending order of their end time (earliest finish first).
    This way, as we process them from left to right, each new interval we encounter is the next earliest finisher among the remaining ones — making it easy to decide which intervals to keep or remove.
  2. Step 2: Scan and count removals.
    Initialize two variables:
    • endOfLastInterval — the end time of the last interval we decided to keep.
    • removalCount — how many intervals we have to remove due to overlaps.
    Then, iterate through each interval currentInterval:
    • If currentInterval starts at or after endOfLastInterval,
      it does not overlap with the last kept one. We can safely keep it and update endOfLastInterval to this interval’s end time.

      Since intervals are sorted by end time, this one ends after all previously kept intervals, so using its end directly is safe for future comparisons.
    • If the currentInterval starts before endOfLastInterval,
      it overlaps with the last kept one. Because the list is sorted by end time, this overlapping interval must finish later than the last kept one.

      Therefore, we remove it (increment removalCount) and do not change endOfLastInterval, which is known to be the earlier finisher than the currentInterval — the greedy choice that leaves more space for future intervals.
  3. Step 3: Return the total number of removals.
    Once we finish scanning all intervals, removalCount represents the smallest number of intervals that must be removed to make the list non-overlapping.

Why This Works

  • Sorting by end time enables greedy skipping:
    Each time we encounter an overlap, we can be sure the current interval ends later than the previously kept one — so keeping it would only block more future intervals.
  • We only compare against the last kept interval:
    We always update endOfLastInterval to the end of the last non-overlapping interval. We can safely use it as a single reference point for deciding whether to keep the current interval, without needing to check any of the earlier ones. This works because we know that no previously kept interval ends earlier than it.
  • The count directly measures the removals needed:
    Instead of explicitly building the non-overlapping list, we just count how many intervals we skip. That count is the minimal number of removals required.

Time Complexity

Sorting the intervals by end time takes O(N log N), where N is the number of intervals. Then we make a single left-to-right pass, checking each interval once (O(N)), giving a total time complexity of O(N log N).

Space Complexity

The greedy scan itself uses only a few scalar variables, giving an O(1) space complexity.
However, since we sort the input first, the overall space complexity depends on the sorting algorithm: typically O(1), O(log N), or O(N).

Visucodize editorial solution titled JS Solution for LeetCode's Non Overlapping Intervals coding problem. Includes code and may include explanation. You can animate the code step by step using the provided input by clicking the run button, or fork it locally to update the code and input for custom visualization. View the original problem at https://leetcode.com/problems/non-overlapping-intervals.