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

 

转载于:https://www.cnblogs.com/lz87/p/10486931.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值