[LeetCode] 435. 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. 

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.

Note:

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

不重叠的区间。

题意是给了一组intervals,求至少需要删除几个interval就能使得最后的结果集中没有重叠。这题又是用到扫描线的思想。既然是找是否有重叠,那么可以根据每个interval的结束时间对input进行排序。排序之后遍历intervals,记录不重叠的interval一共有几个(记为count),然后用intervals的总长度L - count得到最后要的结果。跑个例子,

[[1,2],[2,3],[3,4],[1,3]]

按end排序之后的结果是

[ [ 1, 2 ], [ 2, 3 ], [ 1, 3 ], [ 3, 4 ] ]

之后从第二个interval开始遍历,如果当前interval的start大于等于前一个interval的end,说明两者没有overlap,则count++,说明这两个interval都需要保留。按照这个逻辑,算出最后互不重叠的intervals有多少,再用总数 - count就得到需要剪掉的interval的数量了。

时间O(nlogn)

空间O(1)

JavaScript实现

 1 /**
 2  * @param {number[][]} intervals
 3  * @return {number}
 4  */
 5 var eraseOverlapIntervals = function(intervals) {
 6     // corner case
 7     if (intervals.length === 0) {
 8         return 0;
 9     }
10 
11     // normal case
12     intervals = intervals.sort((a, b) => a[1] - b[1]);
13     let end = intervals[0][1];
14     let count = 1;
15     for (let i = 1; i < intervals.length; i++) {
16         if (intervals[i][0] >= end) {
17             end = intervals[i][1];
18             count++;
19         }
20     }
21     return intervals.length - count;
22 };

Java实现

 1 class Solution {
 2     public int eraseOverlapIntervals(int[][] intervals) {
 3         // corner case
 4         if (intervals.length == 0) {
 5             return 0;
 6         }
 7 
 8         // normal case
 9         Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
10         int end = intervals[0][1];
11         int count = 1;
12         for (int i = 1; i < intervals.length; i++) {
13             if (intervals[i][0] >= end) {
14                 end = intervals[i][1];
15                 count++;
16             }
17         }
18         return intervals.length - count;
19     }
20 }

扫描线相关题目

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/11776268.html