Leetcode 1288 Remove Covered Intervals

本文介绍了如何解决LeetCode第1288题——去除被覆盖区间的问题。通过两种方法实现,一种是先按区间左边界排序,再按右边界排序,另一种是双层循环检查区间包含关系。这两种方法都能有效找出不被其他区间覆盖的区间数量。
摘要由CSDN通过智能技术生成

Leetcode 1288 Remove Covered Intervals

题目

Given a list of intervals, remove all intervals that are covered by another interval in the list.

Interval [a,b) is covered by interval [c,d) if and only if c <= a and b <= d.

After doing so, return the number of remaining intervals.

Example 1:
Input: intervals = [[1,4],[3,6],[2,8]]
Output: 2
Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.

Example 2:
Input: intervals = [[1,4],[2,3]]
Output: 1

Example 3:
Input: intervals = [[0,10],[5,12]]
Output: 2

Example 4:
Input: intervals = [[3,10],[4,10],[5,11]]
Output: 2

Example 5:
Input: intervals = [[1,2],[1,4],[3,4]]
Output: 1

Constraints:

1 <= intervals.length <= 1000
intervals[i].length == 2
0 <= intervals[i][0] < intervals[i][1] <= 10^5
All the intervals are unique.

思路

法一

考虑一种排序的方式,先按interval[0]从小到大排序,再按interval[1]从大到小排序,这样的话可以保证如果有包含关系的两个区间,被包含的一定在包含它的区间的后面出现(因为包含关系的两个区间A包含B,等价于A[0] < B[0], A[1] >= B[1] 或 A[0] = B[0], A[1] >= B[1], 前者因为A[0] < B[0]满足A排序在B前,后者因为A[1] >= B[1]满足A排序在B前)。
所以最后只要遍历,不断记录interval[1]的最大值,当当前interval[1]比最大值小时即为包含(因为该区间的左侧于之前的所有区间都满足包含条件,所以只要任一区间的右侧满足包含条件即为包含),计数扣1。

class Solution {
    public int removeCoveredIntervals(int[][] intervals) {
        if (intervals == null || intervals.length == 0) return 0;
        int res = intervals.length;
        Arrays.sort(intervals, (o1, o2) -> {
            if (o1[0] == o2[0]) return Integer.compare(o2[1], o1[1]);
            return Integer.compare(o1[0], o2[0]);
        });
        int right = -1;
        for (int[] interval : intervals) {
            if (interval[1] <= right) res--;
            right = Math.max(right, interval[1]);
        }
        return res;
    }
}

法二
参考Leetcode Sample代码,直接两层loop搜索intervals[i]是否包含intervals[j]或intervals[j]是否包含intervals[i]。

class Solution {
    public int removeCoveredIntervals(int[][] intervals) {
        int len = intervals.length;
        for (int i = 0; i < intervals.length - 1; i++) {
            if (intervals[i] == null)
                continue;
            int a = intervals[i][0], b = intervals[i][1];
            for (int j = i + 1; j < intervals.length; j++) {
                if (intervals[j] == null)
                    continue;
                int c = intervals[j][0], d = intervals[j][1];
                if (c <= a && b <= d) {
                    len--;
                    break;
                } else if (c >= a && b >= d) {
                    intervals[j] = null;
                    len--;
                }
            }
        }
        return len;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值