持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
题目描述
给定两个由一些 闭区间 组成的列表,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 <= 109
- endi < starti+1
- 0 <= startj < endj <= 109
- endj < startj+1
思路
方法一:暴力解法
两重for循环遍历每一个集合,把两集合的公共区间加入我们的答案数组中,这里唯一的难点就是判断有无交集,这里判断的方法是:用两集合右端点的最小值减去左端点的最大值之间的差和0比较,如果大于等于,说明两个集合有公共区间。
注意:这里可以进行优化:如果i集合的右端点,小于j集合的左端点,说明两集合没有交集,且j后面的集合也没有,可以提前结束小循环
方法二:双指针
两个指针扫描两个数组,如果两个数组有交集(判断方式同暴力解法相同),就把交集加入到答案数组中,这里要注意的时指针移动的条件,两区间求交集后,小区间不会和后面的区间有交集了,但是大区间可能还会有,所以这里每一次循环都要移动小指针的位置。
代码
解法一:
class Solution {
public:
vector<vector<int>> intervalIntersection(vector<vector<int>>& firstList, vector<vector<int>>& secondList) {
int length1 = firstList.size(), length2 = secondList.size();
vector<vector<int>> res;
int j = 0;
for(int i = 0;i < length1;i ++)
{
vector<int> t1 = firstList[i];
for(int j = 0;j < length2;j ++)
{
vector<int> t2 = secondList[j];
// 优化:当第一个区间最大的数小于第二个区间最小的数时,后面的的区间都不用在判断了
if(t1[1] < t2[0]) break;
// 判断有无交集
int qt = min(t1[1], t2[1]) - max(t1[0], t2[0]);
if( qt >= 0)
{
vector<int> ans;
ans.push_back(max(t1[0], t2[0]));
ans.push_back(min(t1[1], t2[1]));
res.push_back(ans);
}
}
}
return res;
}
};
解法二:
class Solution {
public:
vector<vector<int>> intervalIntersection(vector<vector<int>>& firstList, vector<vector<int>>& secondList) {
int length1 = firstList.size(), length2 = secondList.size();
vector<vector<int>> res;
int i = 0, j = 0;
while(i < length1 && j < length2)
{
auto t1 = firstList[i];
auto t2 = secondList[j];
int start = max(t1[0], t2[0]);
int end = min(t1[1], t2[1]);
if(end >= start)
{
vector<int> ans;
ans.push_back(start);
ans.push_back(end);
res.push_back(ans);
}
if(firstList[i][1] < secondList[j][1]) i++;
else j++;
}
return res;
}
};