Reputation: 31
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
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
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