思路:
- 先按照左端点做一个排序(升序),左端点相同的按右端点从小到大排。(时间复杂度O(n2))
- 扫描一遍,挨个判断前一个区间和后一个区间的关系,看是否能够写入。(时间复杂度O(n))
前后关系主要包含以下几种:- 包含(后区间的左端点大于等于前区间左端点,后区间的右端点小于等于前区间的右端点)
- 相交(后区间左端点小于等于前区间的右端点,后区间的右端点大于前区间右端点)
- 相离(后区间左端点值大于前区间右端点的值)
具体实现描述:
先排序,任选一种,这里用冒泡做排序。
然后记录前区间的左右端点值,并扫描后面的每个区间,看是否可以合并。
当前后区间是包含关系时(如下图),则说明后区间没有起到作用,因为前区间包含了后区间的所有信息。故直接扫描下一个区间即可。
当前后区间是相交关系时(如下图),则合并,更新前区间的右端点值,得到一个更长的区间,如图中红色框出的部分。注意,此时还不能写入,因为你不知道合并后的区间与后面区间的关系。
当前后关系是相离时(如下图),这时候则需要把处理后的前区间写入了,因为它不可能再变得更长了。同时需要将前区间的左右端点设置为当前的这个后区间的左右端点值,因为接下来是处理这个后端点的长度问题了。
最后结束后,我们需要把最后一个前区间写入到结果中,因为它处理到最后的时候一定是未写入的。
代码部分
class Solution {
public:
void SwapTwoVector(vector<vector<int>>& intervals,int i,int j)//交换两个向量
{
int temp = intervals[i][0];
intervals[i][0] = intervals[j][0];
intervals[j][0] = temp;
temp = intervals[i][1];
intervals[i][1] = intervals[j][1];
intervals[j][1] = temp;
}
void Write2Vector(vector<vector<int>>& res,int leftValue,int rightValue)//往结果里写入一个区间
{
vector<int> tempVec;
tempVec.push_back(leftValue);
tempVec.push_back(rightValue);
res.push_back(tempVec);
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
//先按照左端点做一个排序(升序),左端点相同的根据右端点大小排。最后每次挨个判断前一个区间和后一个区间的关系
//主要包含以下几种:
// 1、包含(后区间的左端点大于等于前区间左端点,后区间的右端点小于等于前区间的右端点)
// 2、相交(后区间左端点小于等于前区间的右端点,后区间的右端点大于前区间右端点)
// 3、相离(后区间左端点值大于前区间右端点的值)
int len = intervals.size();
int flag = 0,preLeft,preRight,lateLeft,lateRight,k = 0;
vector<vector<int>> res;
if(0 == len)
return res;
//sort
for(int i = 0;i < len;++i)
{
flag = 0;
for(int j = len - 1;j > i;--j)
{
if(intervals[j][0] < intervals[j-1][0])//左小则换
{
SwapTwoVector(intervals,j - 1,j);
flag = 1;
}
else if(intervals[j][0] == intervals[j-1][0] && intervals[j][1] < intervals[j - 1][1])//左等右小,则换
{
SwapTwoVector(intervals,j - 1,j);
flag = 1;
}
}
if(0 == flag)
break;
}
//merge
preLeft = intervals[0][0];
preRight = intervals[0][1];
for(int i = 1;i < len;++i)
{
//拿到当前元素的左右区间
lateLeft = intervals[i][0];
lateRight = intervals[i][1];
if(lateLeft >= preLeft && lateRight <= preRight)//包含 则后区间贡献为0,
continue;
else if(lateLeft <= preRight && lateRight > preRight)//相交 则更新前区间的右端点 此时还不能写入,因为可能继续合并
preRight = lateRight;
else
{
Write2Vector(res,preLeft,preRight);
preLeft = lateLeft;
preRight = lateRight;
}
}
Write2Vector(res,preLeft,preRight);
return res;
}
};
题目
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。