LeetCode(#435):无重叠区间

image

一、前言

本题为LeetCode第435题,是一道 贪心算法 相关的算法题,难度中等。

本题链接:#435. 无重叠区间

二、题目

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。注意:

  1. 可以认为区间的终点总是大于它的起点。
  2. 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

示例1:

// 移除 [1,3] 
Input: [ [1,2], [2,3], [3,4], [1,3] ]
Output: 1

示例2:

// 移除两个 [1,2] 
Input: [ [1,2], [1,2], [1,2] ]
Output: 2

三、思路

       本题求解移除区间的最小数量,是一道求最优解的算法题,并且综合考虑所有区间是否重叠比较复杂,可以分成两个两个地考虑,因此可以使用贪心算法。

       在选择要保留的区间时,保留的区间的结尾越小,留给后面区间的空间就越大,就能够保留更多的区间,因此可以将题目要求转化为求解保留区间的最大数量,贪心策略为:将区间按照结尾大小进行升序排序,优先选择结尾小的区间以及不与其重叠的下一个区间

示例:int[][] interval = [ [1,2], [2,3], [3,4], [1,3] ]

  1. 按照结尾大小进行升序排序; int[][] interval = [ [1,2], [1,3], [2,3], [3,4]]

  2. 分析 [1,2] 与 [1,3] 是否重叠 ;

  3. 重叠,则移除 [1,3] ,分析 [1,2] 与 [2,3] 是否重叠;

  4. 不重叠,因此保留 [2,3];

  5. 分析 [2,3] 和 [3,4] 是否重叠;

  6. 不重叠,则保留 [3,4];

  7. 最终保留区间的最大数量为3,最少移除4-3 = 1个区间。 int[][] interval = [ [1,2], [2,3], [3,4] ]

四、Java代码

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if(intervals.length == 0) return 0;

        // 按照结尾大小升序排序
        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] a, int[] b) {
                return a[1] - b[1];
            }
        });
        // Lambda表达式:  Arrays.sort(intervals, (a,b)-> a[1]-b[1]);

        int count = 1;
        int end = intervals[0][1];
        for(int i = 1; i < intervals.length; i++) {
            if(intervals[i][0] >= end) {
                count++;
                end = intervals[i][1];
            }
        }

        return intervals.length - count;
    }
}
posted @ 2021-03-30 11:26  江子川  阅读(125)  评论(0)    收藏  举报