• 力扣 757. 设置交集大小至少为2


    题目来源:https://leetcode.cn/problems/set-intersection-size-at-least-two/

    大致题意:
    给一组整数区间,找出一个最小的集合 S,使得 S 与每个区间的交集至少有两个元素,返回 S 的长度

    思路

    对于区间 [l1, r1] 和 区间 [l2, r2],若 l1 <= l2,那么有以下情况:

    1. 若 l1 <= l2 < r2 <= r1,那么这两个区间的交集元素大于等于 2 个
    2. 若 l1 < l2 == r1 < r2,那么这两个区间的交集元素只有一个 l2
    3. 若 r1 < l2,那么这两个区间没有交集

    那么,对于以上情况,若使 S 与两个区间的交集元素至少有两个,那么 S 的最小长度为:

    1. S 最小长度为 2,为 l2 和 l2 + 1 即可
    2. S 最小长度为 3,为 l1、l2 和 l2 + 1 即可
    3. S 最小长度为 4,为 l1、l1 + 1、l2 和 l2 + 1 即可

    于是可以将区间按照左边界升序排序,左边界相同的按照右边界降序排序(这样倒序遍历时,左边界相同的两个区间,左侧区间包含右侧区间,那么与右侧区间交集至少为 2 的 S,与左侧区间交集也至少为 2),然后倒序遍历区间,求出 S 的最小长度

    具体实现时:

    1. 首先设集合的长度为 2,元素为最后一个区间的两个最小元素
    2. 倒序遍历,依次比较当前集合两个最小元素与当前区间的交集,根据上述两个区间交集的三种情况增加集合元素

    代码:

    public int intersectionSizeTwo(int[][] intervals) {
            // 将区间按照左边界升序,右边界降序排序
            Arrays.sort(intervals, (a, b) -> {
                if (a[0] == b[0]) {
                    return b[1] - a[1];
                }
                return a[0] - b[0];
            });
            int n = intervals.length;
            int ans = 2;
            // 表示当前交集中最小的两个元素
            int[] cur = new int[]{intervals[n - 1][0], intervals[n - 1][0] + 1};
            for (int i = n - 2; i >= 0; i--) {
                // 当前区间覆盖了交集的两个最小元素,无需扩大交集
                if (intervals[i][1] >= cur[1]) {
                    continue;
                }
                // 当前区间只覆盖了交集的最小元素,需要扩大交集
                if (cur[0] <= intervals[i][1] && intervals[i][1] < cur[1]) {
                    cur[1] = cur[0];
                    // 将交集最小元素设置为当前区间左边界
                    cur[0] = intervals[i][0];
                    ans++;
                } else if (intervals[i][1] < cur[0]) {  // 当前区间与交集没有重合元素
                    cur[0] = intervals[i][0];
                    cur[1] = intervals[i][0] + 1;
                    ans += 2;
                }
            }
            return ans;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    git中怎样忽略.idea/文件和目录
    数据库迁移前后密码的读取方式不同导致识别到密码是错的
    C++---链表
    Linux多路I/O复用入门必读 -- epoll实现原理以及使用方法
    根据身高重建队列
    Postman 正确使用姿势
    verdi fsdb转vcd波形:用于后端功耗分析
    java面试题总结3
    如何解决跨境传输常见的安全及效率问题?
    系统讲解java中list.stream()的用法
  • 原文地址:https://blog.csdn.net/csdn_muxin/article/details/125971115