I would approach this problem with a sweep algorithm. The start and end points of the intervals are events that are placed in the priority queue. You simply move from left to right, stop at each event, and update the current state in accordance with this event.
I made a small implementation in which I use the following Interval class, just for simplicity:
public class Interval { public int start, end; public Interval(int start, int end) { this.start = start; this.end = end; } public String toString() { return "(" + start + "," + end + ")"; } }
The event points mentioned earlier are represented by the following class:
public class AnnotatedPoint implements Comparable<AnnotatedPoint> { public int value; public PointType type; public AnnotatedPoint(int value, PointType type) { this.value = value; this.type = type; } @Override public int compareTo(AnnotatedPoint other) { if (other.value == this.value) { return this.type.ordinal() < other.type.ordinal() ? -1 : 1; } else { return this.value < other.value ? -1 : 1; } }
Now what remains is to create a queue and perform a sweep, as shown in the code below
public class Test { public static void main(String[] args) { List<Interval> interval = Arrays.asList(new Interval(0, 10), new Interval(15, 20)); List<Interval> remove = Arrays.asList(new Interval(2, 3), new Interval(5, 6)); List<AnnotatedPoint> queue = initQueue(interval, remove); List<Interval> result = doSweep(queue);
This leads to:
(0,2) (3,5) (6,10) (15,20)