一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情。
一.题目:
986. 区间列表的交集 给定两个由一些 闭区间 组成的列表,
firstList
和secondList
,其中firstList[i] = [starti, endi]
而secondList[j] = [startj, endj]
。每个区间列表都是成对 不相交 的,并且 已经排序 。
返回这 两个区间列表的交集 。
形式上,闭区间 [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 <= starti < endi <= 10^9
endi < starti+1
0 <= startj < endj <= 10^9
endj < startj+1
二、思路分析:
这道题目依然是关于区间的题目,与上一篇文章的题目不同的是,上一篇文章题目的输入是一个区间,所以我们只需要对一个数组进行处理就好了,而这一道题目给的输入是双区间。
看到双区间进行比较的题目,我们能够想到什么思路进行求解?答案是双指针
,利用双指针
分别指向两个区间的起始部分,然后通过操作进行指针的前进操作。本题的大概思路为:
- 首先我们需要知道两个区间存在交集和不存在交集的区别,由于我们每一个循环都是处理了指针的前进问题了的,所以我们可以不用在代码中写出关于不存在交集的代码;而对于存在交集的区间,我们需要去把所有情况全部写清楚,存在交集区间大致分为四种:1.区间
A
包含区间B
;2.区间A
与区间B
重叠一部分;3.区间B
包含区间A
;4.区间B
在前与区间A
只有一小部分重叠。 - 通过规律发现每次推入的结果都是交集的两个区间的两个起始值的
最大值
和两个终点值的最小值
,所以利用这一点我们直接进行结果集的生成。
三、代码:
/**
* @param {number[][]} firstList
* @param {number[][]} secondList
* @return {number[][]}
*/
var intervalIntersection = function(firstList, secondList) {
let res = []
let lenA = firstList.length
let lenB = secondList.length
if(!lenA || !lenB) return res
//利用双指针指向两个数组
let i = 0
let j = 0
while(i<lenA && j<lenB){
//不存在交集不需要写出因为指针一直向前走
//存在交集发现规律
let a1 = firstList[i][0]
let a2 = firstList[i][1]
let b1 = secondList[j][0]
let b2 = secondList[j][1]
if(b2 >= a1 && a2 >= b1){
res.push([Math.max(a1,b1),Math.min(a2,b2)])
}
//指针向前进
a2 > b2?j++:i++
}
return res
};
四、总结:
这种区间问题大都思路非常明确,需要你通过
画图
来了解全部的过程以及信息,通过画图能够发现隐含的规律进行题目的求解,而对于双区间的比较问题,我们应该能够想到利用双指针
进行区间的相关操作。