分组重叠范围最有效的方法?

时间:2013-09-24 11:25:20

标签: loops collections iteration

我有一个内存中List<Event>,可能是1到50000+长的任何值(不理想,但情况就是)。每个Event都包含openTime属性和closedTime属性,这些属性存储为Long

鉴于事件可能重叠,我需要确定 NO 事件处于活动状态的时间。当你以图形方式查看它并不是很困难。

enter image description here

我已经实施了多个解决方案,但我发现很难找到一个没有重大时间资源影响的解决方案!我目前的解决方案包括:

  1. 迭代收藏品;对于每个值,我通过迭代并查找范围内的任何值来确定集合中的任何其他值是否重叠。
  2. 在范围内逐渐循环每毫秒(大约60000 - 即1小时),并查看当时是否有任何集合元素处于活动状态。
  3. 这些都不是性能友好的,所以对于实现这一目标的有效方法的任何建议都会非常感激吗?

1 个答案:

答案 0 :(得分:1)

班级活动 {     int start,end; }

使用快速排序对事件进行排序,如下所示:

  1. 开始时间小于事件y开始时间的事件x必须首先出现在数组中。
  2. 事件x的开始时间等于事件y开始时间,结束时间少于y结束时间必须首先出现在数组中。
  3. 然后,将inActionEvent设置为事件0。 迭代事件数组,并且对于与inActionEvent不重叠的每个事件,获得它们之间的空闲时间。每次检查inActionEvent和i事件之间的重叠后,如果它们不重叠,则将inActionEvent更改为i事件。如果它们重叠并且我的结束时间大于inActionEvent结束时间,则将inActionEvent设置为i事件。否则保持inActionEvent(inActionEvent可以在我的事件之前开始并在我结束之后结束,在这种情况下你不用iniction事件替换inActionEvent)。

    复杂性: O(n * lg n)用于快速排序,O(n)用于迭代= O(nlgn),有些人可以说它是O(n)

    你的第一个解决方案最少需要O(n * n)。

    这意味着这么快。

    示例代码:

    inActionEvent = 0;
    // dont forget to get free time form time 0 to start time of first event
    for (int i=1;i<numberOfEvents;i++)
    {
        if (!overlap(inActionEvent, i))
        {
            getFreeTimeBetweenThem(inActionEvent, i);
            inActionEvent = i;
        }
        else
        {
            if (events[inActionEvent].endtime<events[i].endtime)
                inActionEvent = i;
            else
                // do nothin
        }
    }
    // again dont forget to get free time from last event endtime to the end of day or something.
    
相关问题