🎈 作者:Linux猿
🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!
🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀
🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬
目录
一、题目描述
1.1 输入描述
1.2 输出描述
1.3 测试样例
1.3.1 示例 1
1.3.2 示例 2
1.3.3 示例 3
二、解题思路
三、代码实现
四、时间复杂度

一、题目描述
给定一组闭区间,其中部分区间存在交集。任意两个给定区间的交集,称为公共区间(如:[1,2], [2,3] 的公共区间为 [2,2], [3,5], [3,6] 的公共区间为 [3,5])。公共区间之间若存在交集,则需要合并(如:[1,3], [3,5]区间存在交集 [3,3],需要合并为[1,5])。按升序排列输出合并后的区间列表。
1.1 输入描述
一组区间列表, 区间数为 N,0 <= N <= 10000。
1.2 输出描述
升序排列的合并后的区间列表
1.3 测试样例
1.3.1 示例 1
输入
4
0 3
1 3
3 5
3 6输出
1 5说明:[0,3] 和 [1,3] 的公共区间为 [1,3],[0,3] 和 [3,5] 的公共区间为 [3,3],[0,3] 和 [3,6] 的公共区间为 [3,3], [1,3] 和 [3,5] 的共区间为 [3,3],[1,3] 和 [3,6] 的共区间为 [3,3], [3,5] 和 [3,6] 的公共区间为 [3,5], 公共区间列表为 [[1,3], [3,3], [3,5]],他们合并后的区间为[1,5]。
1.3.2 示例 2
输入
4
0 3
1 4
4 7
5 8输出
1 3
4 4
5 71.3.3 示例 3
输入
2
1 2
3 4输出
None说明:[1,2] 和 [3,4] 没有交集。
备注:区间元素均为数字,不考虑字母、符号等异常输入;单个区间认定为无公共区间。
二、解题思路
本题主要考查区间合并算法,首先,需要计算两两集合的交集,对计算出的交集进行排序,最后采用贪心的区间合并算法合并有交集的区间即可。
假设交集的区间为(ui, vi),那么区间合并算法为:
(1)设置初始化区间 (u, v) 用于记录合并后的大区间;
(2)合并区间 (ui, vi) 时,如果 v >= ui && v <= vi 那么,更新 v = vi;
(3)否则,如果 v < ui,那么,区间无法合并,更新 u = ui, v = vi;
因为待合并的区间(ui, vi)已经按照 ui <= uj 进行了排序,所以不用考虑 uj > ui 的情况。
三、代码实现
代码实现如下所示。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<pair<int, int>> VectPair;
bool cmp(pair<int, int>a, pair<int, int>b)
{
    if (a.first != b.first) {
        return a.first < b.first;
    }
    return a.second < b.second;
}
VectPair intervalMerge(VectPair g)
{
    // 先计算交集
    int n = g.size();
    VectPair in;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (g[i].second >= g[j].first) {
                in.push_back(pair<int, int>(g[j].first, g[i].second));
            }
        }
    }
    // 处理没有交集的情况
    if (in.size() == 0) {
        return {};
    }
    // 交集排序
    sort(in.begin(), in.end(), cmp);
    // 交集合并
    VectPair ans;
    n = in.size();
    int u = in[0].first;
    int v = in[0].second;
    for (int i = 1; i < n; ++i) {
        if (v >= in[i].first && v <= in[i].second) {
            v = in[i].second;
        } else if (v < in[i].first) {
            ans.push_back(pair<int, int>(u, v));
            u = in[i].first;
            v = in[i].second;
        }
    }
    // 不要忘记添加
    ans.push_back(pair<int, int>(u, v));
    return ans;
}
int main()
{
    int n;
    while (cin>>n) {
        VectPair g;
        int u, v;
        for (int i = 0; i < n; ++i) {
            cin>>u>>v;
            g.push_back(pair<int, int>(u, v));
        }
        auto ans = intervalMerge(g);
        int n = ans.size();
        if (n == 0) {
            cout<<"None"<<endl;
        } else {
            for (int i = 0; i < n; ++i) {
                cout<<ans[i].first<<" "<<ans[i].second<<endl;
            }
        }
    }
    return 0;
}四、时间复杂度
时间复杂度:O(n^2 + mlogm + m)
在上述代码中,n 表述输入的集合数量,m 表示交集数量。那么,求所有集合两两交集的时间是 O(n^2),交集排序的时间复杂度为 O(mlogm),最后,交集合并的时间复杂度为 O(m)。
🎈 感觉有帮助记得「一键三连」支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章」回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞












![LeetCode[684]冗余连接](https://img-blog.csdnimg.cn/img_convert/c02bdcf7bcf2441196d3e09029eb0f3c.png)






