0区间问题中等 LeetCode435. 无重叠区间

435. 无重叠区间

描述

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

分析

模拟去重复区间的行为,这是比较麻烦的,还要去删除区间。可以逆向思考,求从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了。

如何求不相交的区间最多有多少个?*
贪心思想:从左向右遍历,在满足不重叠的条件下,一个区间右边界越小,后面的区间不重叠的概率越大,不相交的区间数量越多。每个区间都这样做,则全局得到最多的不相交的区间。

  • 从左向右遍历,区间右边界越小,则后面的区间不重叠的概率越大,这里需要把右边界的区间尽可能的靠前,因此选择对原数组按照右边界的大小排序,让右边界小的元素靠前。
  • 遍历过程中统计满足不重叠的区间个数

贪心就是这样,代码有时候很简单(不是指代码短,而是逻辑简单),但想法是真的难!
这和动态规划还不一样,动规的代码有个递推公式,可能就看不懂了,而贪心往往是直白的代码,但想法读不懂,哈哈。
https://mp.weixin.qq.com/s?__biz=MzUxNjY5NTYxNA==&mid=2247486198&idx=1&sn=45e3c0d0d98657f47196fa5b8e4914fc&scene=21#wechat_redirect

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        int n = intervals.length;
        if(n == 1){
            return 0;
        }
        Arrays.sort(intervals,new Comparator<int[]>(){
            public int compare(int[] a, int[] b){
                return a[1] - b[1];
            }
        });
        int right = intervals[0][1];
        int sum = 1;
        for(int i = 1; i < n; i++){
            if(intervals[i][0] >= right){
                sum++;
                right = intervals[i][1];
            }
        }
        return n - sum;
    }
}

你可能感兴趣的:(动态规划,leetcode,算法)