LeetCode_双指针_中等_986.区间列表的交集

x33g5p2x  于2022-02-07 转载在 其他  
字(2.2k)|赞(0)|评价(0)|浏览(235)

1.题目

给定两个由一些闭区间组成的列表,firstList 和 secondList ,其中 firstList[i] = [start i, end i] 而 secondList[j] = [start j, end j] 。每个区间列表都是成对不相交的,并且已经排序 。返回这两个区间列表的交集 。

形式上,闭区间 [a, b](其中 a <= b)表示实数 x 的集合,而 a <= x <= b 。
两个闭区间的交集是一组实数,要么为空集,要么为闭区间。例如,[1, 3] 和 [2, 4] 的交集为 [2, 3] 。

示例 1:

输入:firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
输出:[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]

示例 2:
输入:firstList = [[1,3],[5,9]], secondList = [ ]
输出:[ ]

示例 3:
输入:firstList = [], secondList = [[4,8],[10,12]]
输出:[ ]

示例 4:
输入:firstList = 1,7, secondList = 3,10
输出:3,7

提示:
0 <= firstList.length, secondList.length <= 1000
firstList.length + secondList.length >= 1
0 <= start i < end i <= 109
end i < start i+1
0 <= start j < end j <= 109
end j < start j+1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/interval-list-intersections

2.思路

(1)双指针
① 首先分析求两个区间交集的思路:用[start1, end1]、[start2, end2]分别表示firstList、secondList中的两个区间。经过分析可知当且仅当 end2 >= start1 && end1 >= start2 时,这两个区间才有交集,并且交集为 [Math.max(start1, start2), Math.min(end1, end2)]
② 知道了如何求两个区间的交集后,现在便需要遍历firstList、secondList中的区间,并求出区间列表的交集。具体做法如下:
1)定义双指针 i 和 j ,初始时它们分别指向 firstList 和 secondList 的第一个区间;
2)得到当前遍历中 firstList 的区间 [start1,end1],secondList的区间 [start2,end2];
3)判断[start1,end1]、[start2,end2]这两个区间是否有交集,如果有,则其交集为 [Math.max(start1, start2), Math.min(end1, end2)],并将其保存到链表 res 中;
4)如果 end2 >= end1 ,则说明 firstList 中有可能存在其它区间与[start2,end2]有交集 ,所以 i 需要指向 firstList 的下一个区间,即 i++;否则说明 secondList 中有可能存在其它区间与[start1,end1]有交集,所以 j 需要指向 secondList 的下一个区间,即 j++。最后,当某个区间列表遍历结束时,退出循环并将 res 转换为数组即可。

3.代码实现(Java)

//思路1————双指针
public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {
    /*
        (1)由于不知道两个区间列表的交集个数,所以先定义链表res
        (2)将所求的结果保存到res中,然后再将其转换为数组
    */
    List<int[]> res = new LinkedList<>();
    //定义双指针
    int i = 0, j = 0;
    while (i < firstList.length && j < secondList.length) {
        //得到当前遍历中firstList的一个区间[start1,end1],secondList的一个区间[start2,end2]
        int start1 = firstList[i][0], end1 = firstList[i][1];
        int start2 = secondList[j][0], end2 = secondList[j][1];
        //判断[start1,end1]、[start2,end2]这两个区间是否有交集
        if (end2 >= start1 && end1 >= start2) {
            //如果有交集,那么其交集为[Math.max(start1, start2), Math.min(end1, end2)]
            res.add(new int[]{Math.max(start1, start2), Math.min(end1, end2)});
        }
        if (end2 >= end1) {
        	//i指向firstList下一个区间
            i++;
        } else {
        	//j指向secondList下一个区间
            j++;
        }
    }
    return res.toArray(new int[0][0]);
}

相关文章