Sweep Line Algorithm Summary

Given a set of closed intervals, find the smallest set of numbers that covers all the intervals. If there are multiple smallest sets, return any of them.

For example, given the intervals [0, 3], [2, 6], [3, 4], [6, 9], one set of numbers that covers all these intervals is {3, 6}.

 

This problem bcomes clearer if we sort the intervals by the starting points. For example, intervals [[10, 20], [1, 6], [3, 8], [7, 12]] should become [[1, 6], [3, 8], [7, 12], [10, 20]].

Now, to cover the first interval, [1, 6], we must pick a number in between the interval. However, if the next interval intersects, then we can solve an easier interval problem of picking a point between their intersection. This would let us use 1 less point to cover the intervals. Then, we can look at the third intersection and so forth to find the first k intervals which all intersect. Once we find an interval that doesn't intersect, we can pick a point in the intersection of all the previous intervals. Then we repeat the process starting from the current interval.

In the above example, the intersection of [[1, 6], [3, 8]] is [3, 6] while the intersection of [7, 12], [10, 20] is [10, 12].

 

public class SmallestSetToCoverInterval {
    class Interval {
        int start, end;
        Interval(int start, int end) {
            this.start = start;
            this.end = end;
        }

        public int getStart() {
            return start;
        }

        public int getEnd() {
            return end;
        }

        public void setStart(int start) {
            this.start = start;
        }

        public void setEnd(int end) {
            this.end = end;
        }
    }

    public Set<Integer> smallestSetToCoverInterval(Interval[] intervals) {
        Arrays.sort(intervals, Comparator.comparingInt(Interval::getStart));
        Set<Integer> set = new HashSet<>();

        int i = 0;
        while (i < intervals.length) {
            Interval interval = intervals[i];

            while (i < intervals.length && intersect(interval, intervals[i])) {
                interval.setStart(Math.max(interval.start, intervals[i].start));
                interval.setEnd(Math.min(interval.end, intervals[i].end));
                i++;
            }

            set.add(interval.end);
        }
        return set;
    }

    private boolean intersect(Interval i1, Interval i2){
        return !(i1.start > i2.end || i2.start > i1.end);
    }
}

 

posted @ 2019-03-30 01:42  Review->Improve  阅读(717)  评论(0编辑  收藏  举报