EDIT: Actually, just see this answer by @Dave, which is much more efficient.
EDIT: Unfortunately, my previous code is flawed.
For example, with the below input, it outputs the range 99-100 instead of 3-50. Try the new code here.
Range(1, 100), Range(99, 100), Range(2, 50), Range(3, 90)
I wrote another algorithm, but this one is way slower and takes up more space (both time and space complexity are 2^n)
- Make a map called
rangeMap
where the keys are ranges and the values are how many other ranges that range is part of (Integers
)
- For every range
range
in your list of ranges:
- Create another map
createdRanges
, again mapping ranges to integers
- For every entry in
rangeMap
- Define
range2
and n
to be the range and integer that entry holds
- If
range
and range2
overlap:
- Define
newRange
to be that overlapping part
- Define
newN
to be n + 1
, so we know that another range was overlapped by this one
- Add
newRange
to createdRanges
, with the value n + 1
.
- Otherwise, just continue the loop
- Once you're done with that loop, go through every range in
createdRanges
.
- If that range doesn't already exist in
rangeMap
, add that range and the corresponding number that says how many ranges it overlaps.
- Otherwise, check if the value that is already in the map is less than the number of ranges this current range overlaps. If so, update that value.
- Finally, find the entry (or entries) in
rangeMap
with the highest value/number of overlaps, and return the key that maps to that value.
While this is extremely inefficient, if you're going to use it for a large number of ranges, you can optimize it to be less bad by removing ranges for which there exist ranges with more overlaps (or the same number) and are less restrictive, or somehow delaying calculation of ranges, etc.
Link to repl.it