3

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

  • If the question is about finding an algorithm and not about implementing it, perhaps [cs.se] would suit better? (but remember [don't crosspost](https://meta.stackexchange.com/questions/64068/is-cross-posting-a-question-on-multiple-stack-exchange-sites-permitted-if-the-qu) and read their help center before asking) – user202729 Apr 12 '18 at 02:41
  • Just saying "in my opinion does not work at all" does not justify that it doesn't actually work. You need to *explain* why it doesn't work and why your question is not a duplicate. – user202729 Apr 12 '18 at 02:42
  • Brute force would run in O(n^2) so it should meet the problem requirements – Mitch Apr 12 '18 at 03:12
  • @Mitchel0022 please see the difference between Little-O and Big-O notation – Andrej Kováč Apr 12 '18 at 04:00

2 Answers2

1

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.

Obaida.Opu
  • 444
  • 1
  • 4
  • 18
0

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

Pang
  • 9,564
  • 146
  • 81
  • 122
Kupto
  • 2,802
  • 2
  • 13
  • 16