korayucar
7/5/2016 - 1:44 AM

Given many ranges of integers; merge overlapping ranges. Running time is determined by sorting the ranges, thus time complexity is n lg(n).

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();
    }

}