56 lines
1.9 KiB
Markdown
56 lines
1.9 KiB
Markdown
## 题目链接
|
||
https://leetcode-cn.com/problems/merge-intervals/
|
||
|
||
## 思路
|
||
这道题目看起来就是一道模拟类的题,但其实是一道贪心题目!
|
||
|
||
按照左区间排序之后,每次合并都取最大的右区间,这样就可以合并更多的区间了。
|
||
|
||
那有同学问了,这不是废话么? 当然要取最大的右区间啊。
|
||
|
||
**是的,一想就是这么个道理,但它就是贪心的思想,局部最优推导出整体最优**。
|
||
|
||
这也就是为什么很多同学刷题的时候都没有发现自己用了贪心。
|
||
|
||
合并思路:如果 `intervals[i][0] < intervals[i - 1][1]` 即intervals[i]起始位置 < intervals[i - 1]终止位置,则一定有重复,需要合并。
|
||
|
||
如图所示:
|
||
|
||
<img src='../pics/56.合并区间.png' width=600> </img></div>
|
||
|
||
C++代码如下:
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
// 按照区间左边界排序
|
||
static bool cmp (const vector<int>& a, const vector<int>& b) {
|
||
return a[0] < b[0];
|
||
}
|
||
|
||
vector<vector<int>> merge(vector<vector<int>>& intervals) {
|
||
vector<vector<int>> result;
|
||
if (intervals.size() == 0) return result;
|
||
sort(intervals.begin(), intervals.end(), cmp);
|
||
bool flag = false; // 标记最后一个区间有没有合并
|
||
int length = intervals.size();
|
||
|
||
for (int i = 1; i < length; i++) {
|
||
int start = intervals[i - 1][0];
|
||
int end = intervals[i - 1][1];
|
||
while (i < length && intervals[i][0] <= end) { // 合并区间
|
||
end = max(end, intervals[i][1]);
|
||
if (i == length - 1) flag = true; // 最后一个区间也合并了
|
||
i++;
|
||
}
|
||
result.push_back({start, end});
|
||
}
|
||
// 如果最后一个区间没有合并,将其加入result
|
||
if (flag == false) {
|
||
result.push_back({intervals[length - 1][0], intervals[length - 1][1]});
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
```
|