Algorithm - Finding Elementary Intervals in Overlapping Intervals - Stack Overflow
Algorithm - Finding Elementary Intervals in Overlapping Intervals - Stack Overflow
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no
Take the 2-minute tour ×
registration required.
I came across a good question while preparing for some programming interviews.
Given a set of possibly overlapping intervals, you need to write a function to return all elementary intervals among them. For example:
if you are given intervals as the following list of pairs: {{1,5}, {3,10}, {5,11}, {15,18}, {16,20}}, then you need to return the following:
The interval {11,15} is omitted in the answer because it is non-existent in the input.
The interval {1,5} from the input has been split up into {1,3}, {3,5} in the answer because of the starting point "3" defined in {3,10}
in the input that cuts the interval into two elementary intervals.
List<Pair<Integer,#Integer>>#generateElementaryIntervals(List<Pair<Integer,#Integer>#
intervals)
One of the solutions that I imagined was to separate the input into non-intersecting sets, and then a simple O(NlogN) sort over all
numbers in each non-intersecting set will yield the answer. Is there a more efficient way to do it?
algorithm data-structures
I understand quite well, but you have not asked a question. There is not question-mark anywhere in your
post. Do want a solution in Java? Do you just want an idea how to approach it? Have you already thought
about it and are hung up on a specific point? I don't know. – Björn Pollex Dec 14 '11 at 8:48
1 Well, hope I've added some direction to the discussion now with a "?" at the end of the description. –
Kowshik Dec 14 '11 at 8:58
3 Answers
You could break this problem up into nested intervals first, then deal with each nesting
separately. By nested, I mean intervals that share at least one point. For the example you
gave:
{{1,5},#{3,10},#{5,11},#{15,18},#{16,20}}
{1,5},#{3,10},#{5,11}
and
{15,18},#{16,20}
In general, to determine the nestings, you can sort the intervals based on the left endpoint (as
in your example), then run through and start a new nesting whenever you see {x,y},#{x',y'}
with y#<#x' .
For a nesting, the "elementary intervals" are formed by the sorted sequence (without repeats)
of values. In the example, the nestings give
(1,3,5,10,11)#@>#{1,3},#{3,5},#{5,10},#{10,11}
http://stackoverflow.com/questions/8501423/finding-elementary-intervals-in-overlapping-intervals Page 1 of 3
algorithm - Finding elementary intervals in overlapping intervals - Stack Overflow 19/03/15, 15:03
and
(15,16,18,20)#@>#{15,16},#{16,18},#{18,20}
From beginning to {x,y} , make sorted list of endpoints (no repeats), say a0,a1,...,ak
A simple algorithm would be to simply read through the entire list of numbers, and create an
element for each item in each pair.
Each element would store two values: the number , and whether it is the first or second
number (from the input).
Those pairs would then be sorted, first by its internal number , and then by its position ( second
would go before first )
To print out the list of intervals, you would print each number together with the next number,
with the following rules:
You wouldn't print repeated numbers (so for example, you wouldn't print 5,5)
If you exclusively have a second number, and then a first number, you wouldn't print
that elementary interval, since there are no values within that range.
You can sort the endpoints and then iterate in order. In order to know whether you are in or
out you can keep the number of intervals that cover each point. The left end of the interval
contributes +1, while the right contributes -1: (Note that I use TreeMap, which is sorted)
static#class#Pair<T,#K>#{
####public#Pair(T#first,#K#second){
########this.first#=#first;
########this.second#=#second;
####}
####public#String#toString(){
########return#"("#+#first#+#",#"#+#second#+#")";
####}
####T#first;
####K#second;###
}####
static#List<Pair<Integer,#Integer>>#generateElementaryIntervals(List<Pair<Integer,#
Integer>>#intervals)#{
####TreeMap<Integer,#Integer>#overlaps#=#new#TreeMap<Integer,#Integer>();
####for(Pair<Integer,#Integer>#interval#:#intervals){
########int#value#=#overlaps.containsKey(interval.first)#?#overlaps.get(interval.first)+1#
:#1;
########overlaps.put(interval.first,#value);
########value#=#overlaps.containsKey(interval.second)#?#overlaps.get(interval.second)@1#:#
@1;
########overlaps.put(interval.second,#value);
####}
####List<Pair<Integer,#Integer>>##retValue#=#new#ArrayList<Pair<Integer,Integer>>();
http://stackoverflow.com/questions/8501423/finding-elementary-intervals-in-overlapping-intervals Page 2 of 3
algorithm - Finding elementary intervals in overlapping intervals - Stack Overflow 19/03/15, 15:03
####int#overlap#=#0;
####boolean#in#=#false;
####int#last#=#0;
####for(int#point#:#overlaps.keySet()){
########if(in)
############retValue.add(new#Pair(last,#point));
########overlap#+=#overlaps.get(point);
########last#=#point;
########in#=#overlap#>#0;
####}
####return#retValue;
}####
public#static#void#main(String[]#args)#{
####List<Pair<Integer,#Integer>>#l#=#new#ArrayList<Pair<Integer,#Integer>>();
####l.add(new#Pair<Integer,#Integer>(1,5));
####l.add(new#Pair<Integer,#Integer>(3,10));
####l.add(new#Pair<Integer,#Integer>(5,11));
####l.add(new#Pair<Integer,#Integer>(15,18));
####l.add(new#Pair<Integer,#Integer>(16,20));
####for(Object#o#:#generateElementaryIntervals(l)){
########System.out.println(o.toString());
####}
http://stackoverflow.com/questions/8501423/finding-elementary-intervals-in-overlapping-intervals Page 3 of 3