Keep info about the two largest overlapping intervals max1
and max2
(empty in the beginning).
Sort the input list [x1, y1] .. [xn, yn]
= I1..In
by the value x
, discarding the shorter of two intervals if equality is encountered. While throwing intervals out, keep max1
and max2
updated.
For each interval, add an attribute max
in linear time, showing the largest y
value of all preceding intervals (in sorted list):
rollmax = −∞
for j = 1..n do
Ij.max = rollmax
rollmax = max(rollmax, Ij.y)
On sorted, filtered, and expanded input list perform the following query. It uses an ever expanding sublist of intervals smaller then currently searched for interval Ii
as input into recursive function SearchOverlap
.
for i = 2..n do
SearchOverlap(Ii, 1, i − 1)
return {max1, max2}
Function SearchOverlap
uses divide and conquer
approach to traverse the sorted list Il, .. Ir
. It imagines such list as a complete binary tree, with interval Ic
as its local root. The test Ic.max < I.max
is used to always decide to traverse the binary tree (go left/right) in direction of interval with largest overlap with I
. Note, that I
is the queried for interval, which is compared to log(n)
other intervals. Also note, that the largest possible overlapping interval might be passed in such traversal, hence the check for largest overlap in the beginning of function SearchOverlap
.
SearchOverlap(I , l, r)
c = ceil(Avg(l, r)) // Central element of queried list
if Overlap(max1, max2) < Overlap(I , Ic) then
max1 = I
max2 = Ic
if l ≥ r then
return
if Ic.max < I.max then
SearchOverlap(I , c + 1, r)
else
SearchOverlap(I , l, c − 1)
return
Largest overlapping intervals (if not empty) are returned at the end. Total complexity is O(n log(n))
.