Algorithm 在重叠区间中寻找基本区间

Algorithm 在重叠区间中寻找基本区间,algorithm,data-structures,Algorithm,Data Structures,在准备一些节目采访时,我遇到了一个好问题 给定一组可能重叠的区间,您需要编写一个函数来返回其中的所有基本区间。例如:如果给定的间隔为以下对列表:{{1,5}、{3,10}、{5,11}、{15,18}、{16,20},则需要返回以下内容: {1,3}、{3,5}、{5,10}、{10,11}、{15,16}、{16,18}、{18,20} 请注意上述答案中的以下内容: 答案中省略了间隔{11,15},因为它是 在输入中不存在 来自输入的间隔{1,5}已被拆分为{1,3},{3,5} 在答案中,

在准备一些节目采访时,我遇到了一个好问题

给定一组可能重叠的区间,您需要编写一个函数来返回其中的所有基本区间。例如:如果给定的间隔为以下对列表:{{1,5}、{3,10}、{5,11}、{15,18}、{16,20},则需要返回以下内容:

{1,3}、{3,5}、{5,10}、{10,11}、{15,16}、{16,18}、{18,20}

请注意上述答案中的以下内容:

  • 答案中省略了间隔{11,15},因为它是 在输入中不存在
  • 来自输入的间隔{1,5}已被拆分为{1,3},{3,5} 在答案中,因为在{3,10}中定义了起点“3” 将区间分为两个基本区间的输入
Java中的方法签名:


List generateElementaryIntervals(List一个简单的算法是简单地读取整个数字列表,并为每对中的每个项目创建一个元素

每个元素将存储两个值:
数字
,以及它是第一个还是第二个数字(来自输入)

然后将对这些对进行排序,首先按其内部的
编号
,然后按其位置进行排序(
第二个
位于
第一个

要打印间隔列表,您需要按照以下规则打印每个数字和下一个数字:

  • 您不会打印重复的数字(例如,您不会打印5,5)
  • 如果只有一个
    第二个
    编号,然后是
    第一个
    编号,则不会打印该基本间隔,因为该范围内没有值

您可以对端点进行排序,然后按顺序进行迭代。为了知道您是加入还是退出,您可以保留覆盖每个点的间隔数。 间隔的左端贡献+1,而右端贡献-1: (请注意,我使用的是已排序的)

静态类对{
公共对(T第一,K第二){
this.first=first;
这个秒=秒;
}
公共字符串toString(){
返回“(“+first+”、“+second+”)”;
}
T第一;
K秒;
}    
静态列表生成器元素间隔(列表间隔){
树映射重叠=新树映射();
for(配对间隔:间隔){
int value=overlaps.containsKey(interval.first)?overlaps.get(interval.first)+1:1;
重叠.put(interval.first,value);
value=overlaps.containsKey(interval.second)?overlaps.get(interval.second)-1:-1;
重叠.put(interval.second,value);
}
List retValue=new ArrayList();
int重叠=0;
布尔in=false;
int last=0;
for(int point:overlaps.keySet()){
如果(在)
添加(新的一对(最后一点));
重叠+=重叠。获取(点);
最后一个=点;
in=重叠>0;
}
返回值;
}    
公共静态void main(字符串[]args){
列表l=新的ArrayList();
l、 添加(新的一对(1,5));
l、 添加(新的一对(3,10));
l、 添加(新的一对(5,11));
l、 增加(新的一对(15,18));
l、 添加(新的一对(16,20));
对于(对象o:generateElementaryIntervals(l)){
System.out.println(o.toString());
}
}

您可以先将此问题分解为嵌套的间隔,然后分别处理每个嵌套。所谓嵌套,我指的是至少共享一个点的间隔。例如您给出的示例:

{{1,5}, {3,10}, {5,11}, {15,18}, {16,20}}
有两种筑巢方式:

{1,5}, {3,10}, {5,11}

通常,要确定嵌套,您可以根据左端点对间隔进行排序(如示例中所示),然后在看到
{x,y},{x',y'}
y
时运行并开始新的嵌套

对于嵌套,“基本间隔”由排序的值序列(无重复)构成

(1,3,5,10,11) -> {1,3}, {3,5}, {5,10}, {10,11}

因此,整个算法可能如下所示:

  • 根据左端点对间隔进行排序
  • 使用
    y
    运行间隔,直到
    {x,y},{x',y'}
  • 从开始到
    {x,y}
    ,对端点进行排序(无重复),例如
    a0,a1,…,ak
  • i=0…k-1
  • 删除
    {x,y}
    之前的间隔,然后从步骤2继续

你不明白的是什么?我很明白,但你没有问任何问题。你的帖子中没有问号。你想要Java解决方案吗?你只是想知道如何解决这个问题吗?你是否已经考虑过这个问题,并且在某个特定的问题上挂断了电话?我不知道。好吧,希望我为这个问题添加了一些指导现在的讨论在描述的末尾有一个“?”。我认为这是行不通的。例如,您将使用以下序列得到错误的嵌套区间:
{{1,6},{2,3},{4,5}
我不明白你说的“生成端点排序列表”是什么意思。比较器函数是什么。它是否只按间隔中最左边的点排序?我认为这行不通。例如,你会用以下顺序得到错误的答案:{{1,6},{2,3},{4,5}
{15,18}, {16,20}
(1,3,5,10,11) -> {1,3}, {3,5}, {5,10}, {10,11}
(15,16,18,20) -> {15,16}, {16,18}, {18,20}