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

1.9 KiB
Raw Blame History

题目链接

https://leetcode-cn.com/problems/merge-intervals/

思路

这道题目看起来就是一道模拟类的题,但其实是一道贪心题目!

按照左区间排序之后,每次合并都取最大的右区间,这样就可以合并更多的区间了。

那有同学问了,这不是废话么? 当然要取最大的右区间啊。

是的,一想就是这么个道理,但它就是贪心的思想,局部最优推导出整体最优

这也就是为什么很多同学刷题的时候都没有发现自己用了贪心。

合并思路:如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]起始位置 < intervals[i - 1]终止位置,则一定有重复,需要合并。

如图所示:

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;
    }
};