(笔试题)区间最大重叠

题目:

在一维坐标轴上有n个区间段,求重合区间最长的两个区间段。

区间段的数据结构定义如下:

struct Interval{
    int start;
    int end;
};

思路:

首先按照区间的左端点即start对n个区间段进行排序;

然后从前往后遍历所有区间,比较前后两个区间的右端点即end;

假设前后区间分别为[x1,y1],[x2,y2],因为是顺序遍历,因此x2>=x1,考虑一下情况:

 如果y2>=y1,

则在[x2,y2]后面的区间和[x1,y1]的重叠部分不会超过这个区间,因为他们的x>x2,而重叠的区间大小为(y1-x+1)或者为0;因此与区间[x1,y1]重叠的大小最大为y1-x2+1或者0。(当x2>y1时,两个区间不相交,即为0)

如果y2<y1,

那么只能说区间[x2,y2]包含在[x1,y1]里面,这样的话,跟区间[x1,y1]重叠的大小至少为y2-x2+1,而区间2的大小即为y2-x2+1,因此可以不考虑其他区间与区间[x2,y2]的重叠大小。

以上两种情况,我们都可以删除一个区间,计算第一种情况后,可以删除区间1,计算第二种情况后,可以删除区间2。

总的时间复杂度为:排序O(nlogn)+遍历O(n)

代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Interval{
    int start;
    int end;
};

bool cmp(const Interval &a,const Interval &b){
    return a.start<b.start;
}

int longestOverlap(vector<Interval> &inters, int n){
    sort(inters.begin(),inters.end(),cmp);
    for(int i=0;i<n;i++){
        cout<<inters[i].start<<" "<<inters[i].end<<endl;
    }
    int maxOverlap=0;
    Interval pre;
    Interval cur;
    pre=inters[0];
    int len;
    for(int i=1;i<n;i++){
        cur=inters[i];
        if(cur.end>=pre.end){
            len=max(pre.end-cur.start+1,0);
            maxOverlap=max(maxOverlap,len);
            pre=cur;
        }
        else
            maxOverlap=max(maxOverlap,cur.end-cur.start+1);
    }
    return maxOverlap;
}

int main()
{
    int n;
    while(1){
        cin>>n;
        vector<Interval> inters(n);
        for(int i=0;i<n;i++){
            cin>>inters[i].start>>inters[i].end;
        }
        cout<<longestOverlap(inters,n)<<endl;
    }

    return 0;
}

 

posted @ 2015-08-15 11:42  AndyJee  阅读(3626)  评论(0编辑  收藏  举报