Non-overlapping Intervals

Remove the fewest intervals so the rest never overlap: sort by end and greedily keep every interval that starts after the last kept one ends.

Time O(n log n)Space O(1)Code C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

Keeping the most intervals is the same as removing the fewest. Among all intervals, the one that ends first leaves the most room for everything after it, so keep it. Then skip everything that clashes with it and repeat with the next interval that starts at or after its end. Sorting by end makes that a single left-to-right scan with one variable: the end of the last kept interval.

Code

public static int EraseOverlapIntervals(int[][] intervals) {
    Array.Sort(intervals, (x, y) => x[1].CompareTo(y[1]));
    int removed = 0, end = int.MinValue;
    foreach (var iv in intervals) {
        if (iv[0] >= end) {
            end = iv[1]; // keep it: it starts after the last kept one ends
        } else {
            removed++; // it clashes with the last kept interval
        }
    }
    return removed;
}

Tips

In the .NET library

Array.Sort with a Comparison<int[]> sorts the jagged array in place. Use x[1].CompareTo(y[1]) rather than x[1] - y[1]: subtraction can overflow when values are near int.MinValue or int.MaxValue.