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