假设我们定义像这样的间隔
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)解决方案我们可以做得更好吗?
答案 0 :(得分:2)
这是一个简单的O(n log n)
解决方案,它使用事件和扫描线:
有两种类型的事件:间隔的开始和间隔的结束。
我们可以按坐标对所有事件进行排序(如果两个事件具有相同的坐标,那么对应于间隔开始的事件应该更早。如果它们属于同一类型,它们可以进入任何事件顺序)。
现在我们可以遍历有序间隔的数组,并在看到间隔的开始时向计数器添加+1,当我们看到结束时为-1。计数器的最大值就是答案。
为什么这是正确的?在任何时候,计数器的值是在当前位置之前开始并在其之后结束的间隔的数量。这正是我们最大化所需要的。
时间复杂度为O(n log n)
(我们只对事件数组进行排序,然后对其进行一次线性传递)。