30. 区间交集

88 阅读2分钟

题目描述 

给定一组闭区间,其中部分区间存在交集。

任意两个给定区间的交集,称为公共区间(如:[1,2],[2,3]的公共区间为[2,2],[3,5],[3,6]的公共区间为[3,5])。

公共区间之间若存在交集,则需要合并(如:[1,3],[3,5]区间存在交集[3,3],需合并为[1,5])。

升序排列输出合并后的区间列表。

输入描述

一组区间列表,

区间数为 N: 0<=N<=1000;

区间元素为 X: -10000<=X<=10000。

输出描述

升序排列的合并区间列表

备注

  • 区间元素均为数字,不考虑字母、符号等异常输入。
  • 单个区间认定为无公共区间。

用例

输入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,3],[3,3],[3,5]存在交集,须合并为[1,5]。
输入4
0 3
1 4
4 7
5 8
输出1 3
4 4 
5 7
说明
输入2
1 2
3 4
输出None
说明[1,2]和[3,4]无交集

思路:

先找出所有的公共区间(n*(n-1)种),然后在进行排序合并

#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;

int main()
{
    int N;
    cin >> N;

    vector<pair<int, int>> res;

    vector<pair<int, int>> interval(N);
    for (int i = 0; i < N; i++)
    {
        cin >> interval[i].first >> interval[i].second;
    }

    sort(interval.begin(), interval.end(), [](const pair<int, int> &a, const pair<int, int> &b)
         { return a.first < b.first; });

    for (int i = 0; i < N; i++)
    {
        int s1 = interval[i].first;
        int e1 = interval[i].second;
        for (int j = i + 1; j < N; j++)
        {
            int s2 = interval[j].first;
            int e2 = interval[j].second;

            if (s2 <= e1)
            {
                res.push_back(make_pair(s2, min(e1, e2)));
            }
            else
            {
                break;
            }
        }
    }

    if (res.size() == 0)
    {
        cout << "None" << endl;
        return 0;
    }

    // 合并公共区间
    sort(res.begin(), res.end(), [](const pair<int, int> &a, const pair<int, int> &b)
         { return a.first < b.first; });

    vector<pair<int, int>> ans(1, make_pair(res[0].first, res[0].second));
    for (int i = 1; i < res.size(); i++)
    {
        if (res[i].first <= ans.back().second)
        {
            ans.back().second = max(ans.back().second, res[i].second);
        }
        else
        {
            ans.push_back(make_pair(res[i].first, res[i].second));
        }
    }

    for (auto &p : ans)
    {
        cout << p.first << " " << p.second << endl;
    }
}