(合并区间
|| 插入区间)[https://leetcode-cn.com/problems/merge-intervals]
给出一个区间的集合,请合并所有重叠的区间。
示例 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]
可被视为重叠区间。
题目分析
合并区间
- [a,b] [c,d]合并条件:b=c && a<=d
此时区间存在重复区段,可以合并
- 由于原区间序列是乱序,你合并了前两个,产生合并结果temp,但你不知道temp还可以和后续的什么合并,所以又需要遍历一遍,不现实。
- 因此我们先按区间左边界进行排序,这样temp只需要考虑是否还要合并紧挨着的下一个即可。
### 插入区间
- 首先需要找到插入位置,即左边界 介于 前一个和后一个的左边界
中间。
- 插入之后的收尾工作 插入时会不会和前一个发生和合并?
因为是按左边界顺序,因此往前只可能合并一个
但是不知道新区间的右边界延伸到了哪里,因此对后续区间都要检查一遍是否需要合并
题解代码
合并区间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Solution { public: vector<vector<int merge(vector<vector<int& intervals) { vector<vector<int result; int Len=intervals.size(); if(Len==0) return result; sort(intervals.begin(),intervals.end(),cmp); result.push_back(intervals[0]);
int i=1; while(i<Len) { //可连接 [1,3] [2,4] if(intervals[i][0]<=result.back()[1]) if(intervals[i][1]result.back()[1]) result.back()[1]=intervals[i][1]; else; else//不可连接 result.push_back(intervals[i]); i++; }
return result; }
static bool cmp(vector<int& a,vector<int& b) { return a[0]<b[0]; }
};
|
插入区间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| class Solution { public: vector<vector<int insert(vector<vector<int& intervals, vector<int& newInterval) { int i=0; int Len=intervals.size(); bool IsInsert=false; vector<vector<int result; while(i<Len) { //找到插入的位置 if(intervals[i][1]<newInterval[0]) i++; else break; }
if(i==Len)//插在末尾之后 { intervals.push_back(newInterval); return intervals; }
for(int j=0;j<i;j++)//无需检查的项直接插入 result.push_back(intervals[j]);
if(intervals[i][0]<=newInterval[1])//可以合并 { intervals[i][0]=min(intervals[i][0],newInterval[0]); intervals[i][1]=max(intervals[i][1],newInterval[1]); result.push_back(intervals[i]); i++; } else//插入 而不是合并 result.push_back(newInterval);
while(i<Len) { //插入项往后 每一项都要检查是否要往前合并,直到不用合并 if(intervals[i][0]<=result.back()[1]) { if(result.back()[1]<intervals[i][1]) result.back()[1]=intervals[i][1]; } else break; i++; } //出来的i往后是无法合并的项 while(i<Len) { result.push_back(intervals[i]); i++; }
return result;
} };
|