【问题标题】:Algorithm to find intersection of intervals寻找区间交集的算法
【发布时间】:2019-06-24 16:46:18
【问题描述】:

我有两个列表,每组间隔。我想找到两个列表的交集。

Eg.
List1 = [{1, 10}, {15, 25}, {30, 32}];
List2 = [{3,5}, {9,14}, {17,20}];

结果:

IntersectionList = [{3,5}, {9,10}, {17,20}];

尝试过使用: Java algorithm for find intersection between intervals 但这在第一个列表中只有一个对象。

我希望能够在每个列表中提供多个区间对象。

public class CalendarTimeSlot {
    private long from;
    private long to;
}

public class IntersectIntervalsHelper {

        public static void main(String[] args) {

        List<CalendarTimeSlot> l1 = new ArrayList<>();
        l1.add(new CalendarTimeSlot(1, 10));
        l1.add(new CalendarTimeSlot(15, 25));
        l1.add(new CalendarTimeSlot(30, 32));

        List<CalendarTimeSlot> l2 = new ArrayList<>();
        l2.add(new CalendarTimeSlot(3, 5));
        l2.add(new CalendarTimeSlot(9, 14));
        l2.add(new CalendarTimeSlot(17, 20));

        //todo code here to do l1 intersection l2 slots
    }

}

示例输入:

List1 = [{1, 10}, {15, 25}, {30, 32}];
List2 = [{3,5}, {9,14}, {17,20}];

结果:

IntersectionList = [{3,5}, {9,10}, {17,20}];

【问题讨论】:

  • 如果是{9,20},第二个间隔的结果应该是什么?可以是{9,10}{15,20}
  • 两者都必须。 o/p 应包含:[{3,5}, {9,10}, {15,20}];
  • 为什么预期输出显示 2 个列表?是输入错误吗?
  • 你可以用一个BitSet来表示区间,其中每个位索引都是自然数,真/假表示它是否属于区间。然后使用 BitSet.And 方法找到交点。在此之后,以某种方式将结果转储回子间隔列表。
  • 提示:到目前为止,您只放弃了要求。如果您想获得更多积极的反馈...考虑自己尝试一些事情。不要指望其他人应该为你做这项工作。

标签: java algorithm


【解决方案1】:

通过忽略对来展平两个列表并确保它们已排序。您会得到两个数字列表,这样每个间隔都包含在偶数和奇数索引之间(从零开始)。

现在考虑一个标准的合并过程,它将生成第三个列表。

1, 10, 15, 25, 30, 32
3, 5, 9, 14, 17, 20

给予

1, 3, 5, 9, 10, 14, 15, 17, 20, 25, 30, 32

同时,您可以对列表进行注解,以表明您是在任一列表之内还是之外

  1, 3, 5, 9, 10, 14, 15, 17, 20, 25, 30, 32
oo io ii io ii  oi  oo  io  ii  io  oo  io  oo  

所需的输出由ii 间隔组成,

  3, 5, 9, 10, 17, 20
   ii    ii      ii  

【讨论】:

  • 如果第二个列表的第二个元素是 {4,14} 而不是 {9,14} 则不起作用
  • @RobertKock:不允许重叠。如果您允许,我们可以将 inside/outside 替换为“insideness level”。
【解决方案2】:

创建一个包含所有间隔结束的对的列表。
每对都是(value; +1/-1 for interval start/end)
按值排序此列表。
制作ActiveCount=0.
遍历排序列表,使用开始/结束标志递增 ActiveCount
ActiveCount 变为 2 时,输出间隔开始。
ActiveCount 变为 1(在 2 之后!)时,输出间隔结束。

【讨论】:

    【解决方案3】:
    public static List<CalendarTimeSlot> createIntersection(List<CalendarTimeSlot> l1, List<CalendarTimeSlot> l2) {
        List<CalendarTimeSlot> intersectedSlots = new ArrayList<>();
        int length1 = l1.size();
        int length2 = l2.size();
        int l1Counter = 0, l2Counter = 0;
        while (l1Counter<length1 && l2Counter<length2) {
            CalendarTimeSlot calendarTimeSlot1 = l1.get(l1Counter);
            CalendarTimeSlot calendarTimeSlot2 = l2.get(l2Counter);
    
            long from = 0, to =0;
            if(calendarTimeSlot1.getFrom()<=calendarTimeSlot2.getFrom()) {
                from = calendarTimeSlot2.getFrom();
    
                //smaller on is the "to"
                if(calendarTimeSlot1.getTo()>=calendarTimeSlot2.getTo()) {
                    to = calendarTimeSlot2.getTo();
                } else {
                    to = calendarTimeSlot1.getTo();
                }
            } else {
                //l1's from is greater
                if(calendarTimeSlot2.getTo()>calendarTimeSlot1.getFrom()) {
                    from = calendarTimeSlot1.getFrom();
    
                    //smaller on is the "to"
                    if(calendarTimeSlot1.getTo()>=calendarTimeSlot2.getTo()) {
                        to = calendarTimeSlot2.getTo();
                    } else {
                        to = calendarTimeSlot1.getTo();
                    }
                }
            }
    
            if(calendarTimeSlot1.getTo()<calendarTimeSlot2.getTo()) {
                l1Counter++;
            } else {
                l2Counter++;
            }
    
            if(from>0 && to>0) {
                intersectedSlots.add(new CalendarTimeSlot(from, to));
            }
    
        }
    
        return intersectedSlots;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2011-11-29
      相关资源
      最近更新 更多