重叠区间问题

nandizhu 2009-03-27 10:28:59
题目描述:请编写程序,找出下面 “ 输入数据及格式 ” 中所描述的输入数据文件中最大重叠区间的大小。
对一个正整数 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 18 )的重叠区间为 [10 12] ,其大小为 3 ;行 (20 10) 和( 20 30 )的重叠区间大小为 1 。 在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出 0 。


给点思路吧~~~~
...全文
742 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
nandizhu 2009-04-04
  • 打赏
  • 举报
回复
楼上正解
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 nandizhu 的回复:]
你的第二部为什么只需要O(N)呢 ??想不通???

其实实际意义就是把所有数据中被其他数据包含的数据删除,剩下的数据只有两种情况,一:有交集,二:无交集

但是如何做到删除被其他数据包含的数据只用 o(n)呢??
[/Quote]
因为是针对按x排序过的数据进行处理,第二步只要遍历一遍就够了,所以是O(n)
int max=y[1];
for(int i=2; i<=n; i++)
{
if(y[i]>max)
{
max=y[i];
}
else
{
删除第i个区间;
}
}
nandizhu 2009-04-03
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 dlyme 的回复:]
以前和litaoye讨论过一个类似的问题,和这个很像~

首先还是将各行数据整理成x <y的标准形式,然后:
1)将各区间按照x从小到大排序(对于x(i)=x(i+1)这种情况可以优化,只保留较“长”的区间即可。比方说此时有y(i)>y(i+1),那我们只需要保留[x(i),y(i)]区间,而对[x(i+1),y(i+1)]可以省略)——这一步需要O(n*logn);
2)将各区间数据进行整理,保持y严格递增,同时记录下被“删除”区间的最大长度max——这一步需要O(n)…
[/Quote]

你的第二部为什么只需要O(N)呢 ??想不通???

其实实际意义就是把所有数据中被其他数据包含的数据删除,剩下的数据只有两种情况,一:有交集,二:无交集

但是如何做到删除被其他数据包含的数据只用 o(n)呢??
white41612 2009-04-03
  • 打赏
  • 举报
回复
mark
FancyMouse 2009-03-29
  • 打赏
  • 举报
回复
可能普通链表也能干……反正只要是支持按序枚举和O(1)删除的数据结构就可以了
FancyMouse 2009-03-29
  • 打赏
  • 举报
回复
按x排序以后线性转双向链表(需要O(1)的删除)
for(链表头非空)
提取表头线段a,删除a
遍历剩下的表
if(包含)
更新解
删除这个被包含的元素
else
更新解
break;//非包含关系线段里的最优,所以可以break

包含关系部分均摊O(1),非包含关系部分每次迭代都O(1),所以排序后总体O(n)。
  • 打赏
  • 举报
回复
以前和litaoye讨论过一个类似的问题,和这个很像~

首先还是将各行数据整理成x<y的标准形式,然后:
1)将各区间按照x从小到大排序(对于x(i)=x(i+1)这种情况可以优化,只保留较“长”的区间即可。比方说此时有y(i)>y(i+1),那我们只需要保留[x(i),y(i)]区间,而对[x(i+1),y(i+1)]可以省略)——这一步需要O(n*logn);
2)将各区间数据进行整理,保持y严格递增,同时记录下被“删除”区间的最大长度max——这一步需要O(n);
(例如对于[1,5][2,4][3,5][4,7][5,6],为了保证y严格递增,需要删除某些区间,只剩下[1,5][4,7]
这一步的实际含义是统计区间相互“包含”的情况中,最长的“被包含”区间是多少);
3)经过前两步之后,在剩下的区间序列中,不管x还是y都是保持严格递增的(从而保证剩下的区间中不会再出现相互“包含”的情况)。
此时最长的重叠区间只可能有相邻的两个区间产生,遍历统计并更新max——这一步需要O(n)
从而整体只需要O(n*logn)的复杂度,主要花费在排序上。
如果对于已经排好序的数据而言,O(n)线性时间内即可完成。
nandizhu 2009-03-29
  • 打赏
  • 举报
回复
排序后怎么处理??我给的那个方法有点问题。。。
绿色夹克衫 2009-03-28
  • 打赏
  • 举报
回复
也就是这个思路吧,按照x排序,然后遍历1遍应该就能找到最大的那个区间,n*log(n)

不过遍历一遍找最大中间的逻辑还是挺复杂的。
currenttt 2009-03-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 nandizhu 的回复:]
有没有不用排序直接出答案的??~~
[/Quote]
原来有很多数据……

那换种思路,找到所有[x,y]对中最小的x_min和最大的y_max,申请数组int cnt[y_max + 1],初始化为0

对于每个区间[x,y],cnt[x]~cnt[y]++

最后找到所有cnt[i] > 1的,应该就是重叠区间的个数了吧,不知道有没有正确理解LZ的意思
nandizhu 2009-03-28
  • 打赏
  • 举报
回复
有没有不用排序直接出答案的??~~
  • 打赏
  • 举报
回复
应该不是ls的意思,他这里问的是重叠区间的最大长度而不是重叠个数。

像这种问题,排序之后再进行处理会得到比较好的结果,O(n*logn)已经比较理想了,从渐进意义上来说很难再有更快的算法。
nandizhu 2009-03-28
  • 打赏
  • 举报
回复
是找出任意两个区间的重叠区最长。。。。
nandizhu 2009-03-27
  • 打赏
  • 举报
回复
数据是N个

就是N对 [x,y] 并且x>y||x<y

currenttt 2009-03-27
  • 打赏
  • 举报
回复
int min1, max1, min2, max2;

int answer = 0;
[min1, max1], [min2, max2]

if (min2 > max1 || min1 > max2) { /* 无重叠区域,程序返回 */ }
if (min1 > min2) { swap(min1, min2); swap(max1, max2); }
if (max2 > max1) { answer = max1 - min2 + 1; }
else if (max2 <= max1) { answer = max2 - min2 + 1; }
nandizhu 2009-03-27
  • 打赏
  • 举报
回复
只想到了一个 o(nlogn)的。。。。

先把所有整数对调整到 x<y

再根据x从小到大排序

从第一个点对(x1,y1)开始,

把之后的所有xi>x1&&yi<y1找出(被x1,y1包含的且x值从小到大) (1)

那么最长的那个就是覆盖的最多的区间长度 刷新MAX(因为是按照X排序,所有满足xi>x1&&yi<y1都不用再互相比较了)

再次,计算xi+1,yi+1与x1,y1的重叠区域(yi+1>y1)刷新MAX

再重复 (1)步,所有被xi+1,yi+1包含的余下点对,找出最长的那个刷新MAX(这些点也不用和前面x1,y1和它所包含的点对比较)

如此循环

这样总的比较次数是n ,排序用时nlogn

总的算法复杂度是nlogn

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧