Interval Interval scheduling problem of intersection
Interval Scheduling wrote a total of 3 blog, the first two overlapping sections and sections merger were told interval 最大不相交子集和重叠区间的合并
, write an algorithm today, you can 快速找出两组区间的交集
.
First, the problem-solving ideas
Interval ideas to solve the problem in general is 先排序
, in order to operate, but the topic that has been sorted, then you can 用两个索引指针在 A 和 B 中游走,把交集找出来
code something like this:
# A, B 形如 [[0,2],[5,10]...]
def intervalIntersection(A, B):
i, j = 0, 0
res = []
while i < len(A) and j < len(B):
# ...
j += 1
i += 1
return res
Difficult, let's honestly analyze various situations.
First, for two intervals, we use [a1, a2] and [b1, b2] represents the two sections A and B, then there is no intersection of these two intervals under what circumstances it :
Only these two cases, written conditional code is this:
if b2 < a1 or a2 < b1:
[a1,a2] 和 [b1,b2] 无交集
So, under what circumstances, there is the intersection of two intervals it? According to deny the proposition, the logic of the above proposition is whether the presence of intersection:
# 不等号取反,or 也要变成 and
if b2 >= a1 and a2 >= b1:
[a1,a2] 和 [b1,b2] 存在交集
Next, the case of two intervals intersection exists, what does? 穷举
come out:
It is very simple, it is these four cases only. So then I think, under these types of situations, whether there is an intersection in common?
We were surprised to find that the intersection interval is regular! If the intersection is the interval [c1, c2],Then c1 = max (a1, b1), c2 = min (a2, b2)! This is to find the intersection of the core , we further the code:
while i < len(A) and j < len(B):
a1, a2 = A[i][0], A[i][1]
b1, b2 = B[j][0], B[j][1]
if b2 >= a1 and a2 >= b1:
res.append([max(a1, b1), min(a2, b2)])
# ...
The final step, we pointer i and j are sure to advance (increment), and when should it go forward?
Whether 只取决于 a2 和 b2 的大小关系
forward . Code:
while i < len(A) and j < len(B):
# ...
if b2 < a2:
j += 1
else:
i += 1
Complete code:
# A, B 形如 [[0,2],[5,10]...]
def intervalIntersection(A, B):
i, j = 0, 0 # 双指针
res = []
while i < len(A) and j < len(B):
a1, a2 = A[i][0], A[i][1]
b1, b2 = B[j][0], B[j][1]
# 两个区间存在交集
if b2 >= a1 and a2 >= b1:
# 计算出交集,加入 res
res.append([max(a1, b1), min(a2, b2)])
# 指针前进
if b2 < a2: j += 1
else: i += 1
return res
C ++ code:
class Solution {
public:
vector<vector<int>> intervalIntersection(vector<vector<int>>& A, vector<vector<int>>& B) {
//保存结果
vector<vector<int>> ret;
if(A.empty() || B.empty())
{
return ret;
}
//i和j两个下标索引
int i = 0;
int j = 0;
while(i < A.size() && j < B.size())
{
//下面四个变量的含义相见博客
int a1 = A[i][0];
int a2 = A[i][1];
int b1 = B[j][0];
int b2 = B[j][1];
//代表区间有交集,自己画个图就OK
if(b2 >= a1 && a2 >= b1)
{
//max(a1,b1),min(a2,b2)两个区间的交集部分
ret.push_back({max(a1,b1),min(a2,b2)});
}
//更新i和j下标索引,b2 < a2 就代表i所在的区间大于j所在的区间,更新j
//是因为i区间长于j区间的部分还可能和j的下一个区间继续重叠,还需要继续判断
//所以更新j而不是更新i
if(b2 < a2)
{
j++;
}
else//反之同理
{
i++;
}
}
return ret;
}
};
To summarize, the section looks like the problem is more complex, difficult to handle a lot of situations, but in fact can be found by observing the law of commonality between different situations, can handle with simple code.