↓Skip to main content
  1. LeetCode/

LeetCode 435: Non-overlapping Intervals

·2 mins· ·
LeetCode Medium Array Dynamic-Programming Greedy Sorting
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-11-16

  • Submissions: Wrong Answer → Accepted → Wrong Answer ×2 → Runtime Error → Wrong Answer → Accepted

Approach
#

Removing the fewest means keeping the most disjoint intervals (Greedy Template 2). Sort by right end; scanning left to right, keep an interval whose start is >= the last kept end, otherwise remove it. Keeping the earliest end leaves the most room.

Sorting by start also works: on an overlap remove one, keeping the smaller right end (end = min(end, b)).

My Attempts
#

I sorted by start:

  • On 2022-11-16 attempt 1 kept the larger right end (max) on an overlap; keeping the smaller one makes later intervals collide less. min passed.
  • A 2022-11-27 rewrite never updated the right end after an overlap and started from [0, 0], failing with negative starts; four failures later I returned to the correct form.

Solution
#

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda x: x[1])
        end, kept = float("-inf"), 0
        for a, b in intervals:
            if a >= end:
                kept += 1
                end = b
        return len(intervals) - kept

Complexity
#

Time O(n log n), space O(1) apart from sorting.

Mistakes to Avoid
#

  • Touching endpoints do not overlap; use >=.
  • When sorting by start, keep the shorter of two overlapping intervals (min of the right ends), not max.

Interview Explanation
#

Removing the fewest means keeping the most disjoint intervals, so I sort by right end, keep each interval starting at or after the last kept end, and subtract. Keeping the earliest end leaves the most room. Time O(n log n).

Related

LeetCode 313: Super Ugly Number
·2 mins
LeetCode Medium Array Math Dynamic-Programming
LeetCode 313 note: generalizing LC 264 with one pointer per prime; with a heap, avoid pushing the same number many times
LeetCode 396: Rotate Function
·2 mins
LeetCode Medium Array Math Dynamic-Programming
LeetCode 396 note: F(k) and F(k - 1) differ by one formula: F(k) = F(k - 1) + sum - n × the element moved to the front
LeetCode 397: Integer Replacement
·2 mins
LeetCode Medium Dynamic-Programming Greedy Bit-Manipulation Memoization
LeetCode 397 note: even numbers are always halved; for odd numbers try +1 and -1 with memoized recursion, since n is too large for an n-sized array
LeetCode 473: Matchsticks to Square
·2 mins
LeetCode Medium Array Dynamic-Programming Backtracking Bit-Manipulation
LeetCode 473 note: the total must be divisible by 4; place sticks from longest to shortest into one of four sides, skipping a side that would overflow or that equals a side already tried
LeetCode 229: Majority Element II
·2 mins
LeetCode Medium Array Hash-Table Sorting Counting
LeetCode 229 note: at most two values can exceed n / 3; Boyer-Moore keeps two candidates and a second pass verifies their counts
LeetCode 134: Gas Station
·2 mins
LeetCode Medium Array Greedy
LeetCode 134 note: if total gas is short there is no answer; otherwise scan, and whenever the tank goes negative move the start to the next station