zoukankan      html  css  js  c++  java
  • LeetCode 435. Non-overlapping Intervals

    435. Non-overlapping Intervals

    Description Submission Solutions Add to List

    • Total Accepted: 7406
    • Total Submissions: 18525
    • Difficulty: Medium
    • Contributors: love_FDU_llp

    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:

    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. 

    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.

    Subscribe to see which companies asked this question.

    【题目分析】

    这个题目与《算法导论》中活动安排的题目非常类似。

    活动选择问题
    有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。

    考虑使用贪心算法的解法。为了方便,我们用不同颜色的线条代表每个活动,线条的长度就是活动所占据的时间段,蓝色的线条表示我们已经选择的活动;红色的线条表示我们没有选择的活动。
    如果我们每次都选择开始时间最早的活动,不能得到最优解:

    如果我们每次都选择持续时间最短的活动,不能得到最优解:

    可以用数学归纳法证明,我们的贪心策略应该是每次选取结束时间最早的活动。直观上也很好理解,按这种方法选择相容活动为未安排活动留下尽可能多的时间。这也是把各项活动按照结束时间单调递增排序的原因。

    【思路】

    参照上面活动安排的例子,我们很容易得到这个题目的解法。这是一个贪心问题,我们每次都找到那个结束点最小的区间,然后依次向后找那些与前面区间不冲突且结束点早的区间。这个过程中我们把局部的最优解合并成了全局的最优解。

    【java代码】

     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         
    14         Comparator<Interval> comp = new Comparator<Interval>() {
    15             public int compare(Interval interval1, Interval interval2) {
    16                 if(interval1.end > interval2.end) return 1;
    17                 else if(interval1.end < interval2.end) return -1;
    18                 else return 0;
    19             }
    20         };
    21         
    22         Arrays.sort(intervals, comp);
    23         int lastend = intervals[0].end;
    24         int remove = 0;
    25         for(int i = 1; i < intervals.length; i++) {
    26             if(intervals[i].end == lastend) remove++;
    27             else if(intervals[i].start < lastend) remove++;
    28             else lastend = intervals[i].end;
    29         }
    30         
    31         return remove;
    32     }
    33 }
  • 相关阅读:
    2021年4月28日
    2021年4月18日
    2021年3月4日
    2020年11月20日
    20201112
    ThreadLocal原理分析
    git与gitlab
    DevOps与CICD简介
    代码扫描利器sonarqube
    看完小白也会使用,Android投屏神器scrcpy详细教程
  • 原文地址:https://www.cnblogs.com/liujinhong/p/6399198.html
Copyright © 2011-2022 走看看