Given many ranges of integers; merge overlapping ranges. Running time is determined by sorting the ranges, thus time complexity is n lg(n). After preprocessing; merging is done in O(n) time.
/**
* You are given a sorted list of disjoint intervals and an interval, e.g. [(1, 5), (10, 15), (20, 25)] and *(12, 27).
* Your task is to merge *them into a sorted list of disjoint intervals: [(1, 5), (10, 27)].
*/
/** there is not internal synchronisation in this class */
import java.util.*;
public class RangeSetBuilder {
private Set<IntRange> ranges = new TreeSet<>();
public static class IntRange implements Comparable<IntRange> {
int start;
int end;
public IntRange(int start, int end) {
this.start = start;
this.end = end;
}
public IntRange(IntRange source) {
this.start = source.start;
this.end = source.end;
}
@Override
public int compareTo(IntRange other) {
return start - other.start;
}
private boolean intersects(IntRange other) {
return other.end >= start && end >= other.start;
}
}
public void addRange(IntRange range) {
ranges.add(range);
}
public List<IntRange> compressedRange() {
List<IntRange> compressedSet = new ArrayList<>();
IntRange previous = null;
for (IntRange event : ranges) {
if (previous == null || !previous.intersects(event)) {
previous = new IntRange(event);
compressedSet.add(previous);
}
else
previous.end = Math.max(previous.end, event.end);
}
return compressedSet;
}
public void printCompressedView() {
List<IntRange> ranges = compressedRange();
System.out.print("[");
for (IntRange r : ranges)
System.out.print(" ( " + r.start + "-" + r.end + " ) ");
System.out.print("]");
System.out.println();
}
public static void main(String... args) {
RangeSetBuilder builder = new RangeSetBuilder();
builder.addRange(new RangeSetBuilder.IntRange(1, 5));
builder.addRange(new RangeSetBuilder.IntRange(10, 15));
builder.addRange(new RangeSetBuilder.IntRange(20, 25));
builder.addRange(new RangeSetBuilder.IntRange(12, 27));
builder.printCompressedView();
builder.addRange(new RangeSetBuilder.IntRange(5, 9));
builder.printCompressedView();
builder.addRange(new RangeSetBuilder.IntRange(27, 39));
builder.printCompressedView();
builder.addRange(new RangeSetBuilder.IntRange(9, 10));
builder.printCompressedView();
}
}