快捷搜索: 王者荣耀 脱发

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

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

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]);
}
经验分享 程序员 微信小程序 职场和发展