leetcode-master/problems/0056.合并区间.md

56 lines
1.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 题目链接
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;
}
};
```