(笔试题)区间最大重叠
题目:
在一维坐标轴上有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; }