无重叠区间——贪心算法

2021-08-24 18:00:42 浏览数 (1)

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

注意:

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

示例 1:

输入: [ [1,2], [2,3], [3,4], [1,3] ] 输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

输入: [ [1,2], [1,2], [1,2] ] 输出: 2

解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

输入: [ [1,2], [2,3] ] 输出: 0

解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

题解:又是给了一组数组,问之间有无重叠区间,显然可以考虑将其排序之后,逐个比较,考虑局部最优解,符合贪心算法思想

因为区间的终点始终大于它的起点,我们考虑将其按照终点大小,由小到大排序

这里直接调用Arrays.sort()进行排序,以下为Lambda表达式写法

Arrays.sort(intervals, new Comparator<int[]>() { public int compare(int[] interval1, int[] interval2) { return interval1[1] - interval2[1]; } });

这里重写了compare方法,interval1[1] - interval2[1],即由小到大interval1[1] < interval2[1]进行排序

简化版Lambda写法:

Arrays.sort(intervals,(o1,o2) -> o1[1] < o2[1]);

排完序后我们考虑:依次从最左边区间的右边界和下一区间的左边界比较

int count = 0, prev = intervals[0][1]; for(int i = 1;i < n;i ){ if(prev > intervals[i][0]) count ; else prev = intervals[i][1]; }

若右边界大于左边界,则说明区间重叠,需移除一个,再和下一区间左边界比较,此时count ;

若小于等于,则说明,区间无重叠,这时取到下一区间的右边界,向右递进,再和下下区间的左边界进行比较,直至到达数组末尾。

Java代码:

代码语言:javascript复制
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0)
            return 0;
        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[1] - interval2[1];
            }
        });
        int count = 0, prev = intervals[0][1];
        for(int i = 1;i < intervals.length;i  ){
            if(prev > intervals[i][0]) count  ;
            else prev = intervals[i][1];
        }
    return count;
    }
}

C :

代码语言:javascript复制
class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
            if (intervals.empty()) {
            return 0;
            }
        int n = intervals.size();
        sort(intervals.begin(), intervals.end(), [](vector<int> a, vector<int> b) {
        return a[1] < b[1];
        });
        int count = 0, prev = intervals[0][1];
        for(int i = 1;i < n;i   ){
            if(prev > intervals[i][0])
                count  ;
            else 
            prev = intervals[i][1];
        }
        return count;
    }
};

这是一个Medium难度题,但当我们思考其特征(给了一组数组数据,区间重叠是局部问题,且没有后效性),发现符合贪心算法,接着找出贪心策略(即排序后依次比较),我们发现此题还是可以简洁性的处理。

0 人点赞