现在的位置: 首页 > 综合 > 正文

【算法1】最大重叠子区间

2013年02月26日 ⁄ 综合 ⁄ 共 1131字 ⁄ 字号 评论关闭

问题描述

对一个正整数n,如果n在数据文件中某行的两个正整数(假设为A和B)之间,即A<=n<=B或A>=n>=B,则n属于该行;如果n同时属于行i和j,则i和j有重叠区间;重叠区间的大小是同时属于行i和j的整数个数。例如,行(10 20)和(12 25)的重叠区间为[12 20],其大小为9;行(20 10)和(12 8)的重叠区间为[10 12],其大小为3;行(20 10)和(20 30)的重叠区间大小为1。 

输入数据:程序读入已被命名为input.txt的输入数据文本文件,该文件的行数在1到1,000,000之间,每行有用一个空格分隔的2个正整数,这2个正整数的大小次序随机,每个数都在1和2^32-1之间。 

输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出0。

解题思路

定义下界为区间的左端,上界为区间的右端。对每个区间的下界从小到大进行排序,若两个区间的下界相同,则按上界从小到大进行排序。定义一个max_overlap=0存放当前得到的最大重叠区间,之后顺序处理,假设区间存放在一个结构体里,定义如下:

struct regins{
     int left;//区间上界
     int right;//区间下界
}

如果regins[i].left<regins[i-1].right,说明这两个区间相交,分为两种情况:

1、regins[i-1].right>regins[i].right

2、regins[i-1].right<regins[i].right


综合上述两种情况,令right_small=min(regins[i].right,regins[i1].right),找出两个线段上界较小的那个,得到相交区间为right_small-regins[i].left+1,如果该值大于max_overlap,则更新max_overlap。

考虑下面一种情况:


regins[i-1]的上界大于regins[i]的上界,需要将regins[i-1]的上界替换给regins[i],就是上图的红色线段部分,然后regins[i]再与regins[i-1]求相交区间,其实也好理解,当regins[i]包含在上一段时,我实际希望比较的是regins[i+1]与regins[i-1],但这个时候,并不关心比regins[i-1].left小的那部分。

令right_big=max(regins[i].right,regins[i-1].right),找出两个线段中上界较大的那个,把b的值赋给regins[i].right,继续下一步的处理。

排序的时间复杂度为O(nlogn),比较更新的复杂度为O(n),总的复杂度为O(n)


程序实例
<soon>

抱歉!评论已关闭.