给定间隔矢量输出在重叠最多次的间隔内的任何一个数字

时间:2015-03-24 16:58:48

标签: c++ algorithm sorting

假设我们定义像这样的间隔

struct Interval {
  float start;
  float end;
  Interval() : start(0), end(0) {}
  Interval(float s, float e) : start(s), end(e) {}

};

如何在重叠次数最多的时间间隔内输出任何一个数字?

例如,[1.2,3.4],[2.6,6.8],[8.5,10.2],[15.1,18.7] 我们可以输出[2.6,3.4]中的任何数字,如2.7,因为[2.6,3.4]是重叠次数最多的区间(两次)。

我的想法是按照"开始"对间隔进行排序。然后在所有间隔中运行for循环。对于每个间隔,我们计算下面的间隔小于或等于"结束"的数量,并且每个循环更新最大值。

但这看起来像O(n2)解决方案我们可以做得更好吗?

1 个答案:

答案 0 :(得分:2)

这是一个简单的O(n log n)解决方案,它使用事件和扫描线:

  1. 有两种类型的事件:间隔的开始和间隔的结束。

  2. 我们可以按坐标对所有事件进行排序(如果两个事件具有相同的坐标,那么对应于间隔开始的事件应该更早。如果它们属于同一类型,它们可以进入任何事件顺序)。

  3. 现在我们可以遍历有序间隔的数组,并在看到间隔的开始时向计数器添加+1,当我们看到结束时为-1。计数器的最大值就是答案。

  4. 为什么这是正确的?在任何时候,计数器的值是在当前位置之前开始并在其之后结束的间隔的数量。这正是我们最大化所需要的。

  5. 时间复杂度为O(n log n)(我们只对事件数组进行排序,然后对其进行一次线性传递)。