Leetcode: Non-overlapping Intervals

Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.

Note:
You may assume the interval's end point is always bigger than its start point.
Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other.
Example 1:
Input: [ [1,2], [2,3], [3,4], [1,3] ]

Output: 1

Explanation: [1,3] can be removed and the rest of intervals are non-overlapping.
Example 2:
Input: [ [1,2], [1,2], [1,2] ]

Output: 2

Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping.
Example 3:
Input: [ [1,2], [2,3] ]

Output: 0

Explanation: You don't need to remove any of the intervals since they're already non-overlapping.

Actually, the problem is the same as "Given a collection of intervals, find the maximum number of intervals that are non-overlapping." (the classic Greedy problem: Interval Scheduling). With the solution to that problem, guess how do we get the minimum number of intervals to remove? : )

Sorting Interval.end in ascending order is O(nlogn), then traverse intervals array to get the maximum number of non-overlapping intervals is O(n). Total is O(nlogn).

开始的时候想岔了,以为是要求同一时刻overlap的最多interval数,但仔细想一想就发现不对,应该是non-overlap的interval的最大数目

1. Best solution: sorted by interval end

case 1 add current interval as another non-overlapping interval, case 2 and case 3 all get rid of the current interval


Non_overlapping

 1 /**
 2  * Definition for an interval.
 3  * public class Interval {
 4  *     int start;
 5  *     int end;
 6  *     Interval() { start = 0; end = 0; }
 7  *     Interval(int s, int e) { start = s; end = e; }
 8  * }
 9  */
10 public class Solution {
11     public int eraseOverlapIntervals(Interval[] intervals) {
12         if (intervals.length == 0) return 0;
13         int nonOverlap = 1;
14         int seq = 0;
15         Arrays.sort(intervals, new Comparator<Interval>() {
16             public int compare(Interval i1, Interval i2) {
17                 return i1.end - i2.end;
18             }
19         });
20         for (int i=1; i<intervals.length; i++) {
21             if (intervals[i].start >= intervals[seq].end) {
22                 seq = i;
23                 nonOverlap++;
24             }
25         }
26         return intervals.length - nonOverlap;
27     }
28 }

 Comparator can also be rewritten as

1 Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[1], i2[1]));

2. Alternatives(not the best): sort by interval start

case 1 add current interval as another non-overlapping interval, case 2 update the previous non-overlapping interval with the current one, and case 3 get rid of the current interval. So more cases need to be processed than sorted by interval end

Non_overlapping

 1 class Solution {
 2     public int eraseOverlapIntervals(int[][] intervals) {
 3         if (intervals.length < 1) return 0;
 4         int seq = 0;
 5         int nonOverlap = 1;
 6         
 7         Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));
 8         
 9         for (int i = 0; i < intervals.length; i ++) {
10             if (intervals[i][0] >= intervals[seq][1]) {
11                 seq = i;
12                 nonOverlap ++;
13             }
14             else if (intervals[i][1] <= intervals[seq][1]) {
15                 seq = i;
16             }
17         }
18         
19         return intervals.length - nonOverlap;
20     }
21 }
原文地址:https://www.cnblogs.com/EdwardLiu/p/6139762.html