leetcode 第57题插入区间
问题分析
问题如下(传送门)
这里要将newInerval插入到intervals中,并保持给定的顺序,此外,还可能会涉及到区间的合并。
我们将问题简单化,被插入的序列有两个数,每个数在待插入序列中的位置只会存在两种情况,即在某个区间内,或在区间之外,所以整个问题只会在下面四种情况之一:
左操作数是否在区间内 | 右操作数是否在区间内 |
---|---|
1 | 1 |
1 | 0 |
0 | 1 |
0 | 0 |
先把这四种情况放到一边,再来看看,将newInerval插入后,它的左右值是否要改变,如果要改变的话,应该变为多少。
根据以上两点,就可以将问题再具体一点
第一种情况:左右值都在某个区间内,那么最后插入的区间肯定左值是原左值所在区间的左值,右值是原右值所在区间的右值。说起来太绕了,直接看下面的例子:
最后的结果就是: [[2,3], [5,19], [200, 1600]];
第二种情况:由于左值在某个区间,所以最后插入区间的左值是原左值所在区间的左值,右值还是那个右值,如下:
结果为: [[2,3], [5,11], [16, 19],[200, 1600]];
第三种情况和第二种类似
第四种情况:左右值均不变
结果为:[[2,3], [4,11], [16,19], [200, 1600]]。
答案只有上面四种情况,现在还是剩下一个点,就是合并的问题。这个也很简单,只要在遍历待插入区间的时候,将左值和右值之间的区间全部合并就好了,一次遍历即可。
源码
class Solution
{
public:
vector<vector<int>> insert(vector<vector<int>> &intervals, vector<int> &newInterval)
{
vector<vector<int>> ret;
int left = -1, right = -1;
for (auto it = intervals.begin(); it != intervals.end(); it++)
{
if (left == -1)
{
if (newInterval[0] < (*it)[0])
left = newInterval[0];
else if (newInterval[0] <= (*it)[1])
left = (*it)[0];
}
if (left != -1 && right == -1)
{
if (newInterval[1] < (*it)[0])
right = newInterval[1];
else if (newInterval[1] <= (*it)[1])
right = (*it++)[1];
else
continue;
}
if (right != -1)
{
ret.push_back(vector<int>{left, right});
ret.insert(ret.end(), it, intervals.end());
break;
}
ret.push_back(*it);
}
if (left == -1)
ret.push_back(newInterval);
else if (right == -1)
ret.push_back(vector<int>{left, newInterval[1]});
return ret;
}
};