Andrej Kováč
Andrej Kováč

Reputation: 31

Finding longest overlapping interval pair

Say I have a list of n integral intervals [a,b] each representing set S = {a, a+1, ...b}. An overlap is defined as |S_1 \cap S_2|. Example: [3,6] and [5,9] overlap on [5,6] so the length of that is 2. The task is to find two intervals with the longest overlap in Little-O(n^2) using just recursion and not dynamic programming.

Naive approach is obviously brute force, which does not hold with time complexity condition. I was also unsuccessful trying sweep line algo and/or Longest common subsequence algorithm.

I just cannot find a way of dividing it into subproblems. Any ideas would be appreciated.

Also found this, which in my opinion does not work at all:

Finding “maximum” overlapping interval pair in O(nlog(n))

Upvotes: 3

Views: 2979

Answers (2)

Kupto
Kupto

Reputation: 2992

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)).

Upvotes: 0

Obaida.Opu
Obaida.Opu

Reputation: 464

Here is an approach that takes N log(N) time.

Breakdown every interval [a,b] [c,d] into an array of pair like this:

pair<a,-1>
pair<b,a>
pair<c,-1>
pair<d,c>

sort these pairs in increasing order. Since interval starts are marked as -1, in case of ties interval they should come ahead of interval ends.

for i = 0 to end of the pair array
    if current pair represents interval start
        put it in a multiset
    else
        remove the interval start corresponding to this interval end from the multiset.
        if the multiset is not empty
            update the maxOverlap with (current_interval_end - max(minimum_value_in_multiset,start_value_of_current_interval)+1)

This approach should update the maxOverlap to the highest possible value.

Upvotes: 1

Related Questions