[LeetCode] 352. Data Stream as Disjoint Intervals

题目描述

Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals.

For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ..., then the summary will be:

[1, 1]
[1, 1], [3, 3]
[1, 1], [3, 3], [7, 7]
[1, 3], [7, 7]
[1, 3], [6, 7]

 具体解法

 这道题很类似于LeetCode中的一道合并区间的问题,我对于这道题的做法就是使用有序的set,也就是treeSet,然后自定义比较器,规定其比较的规则,在本题中,我是以start将区间进行递增排序的,每次新插入一个值,会将第一个start<val的对象拿出,然后看是否包含了val,判断的依据就是拿出来的floor.end是否>=val,如果没有包含,在判断end和val是否是相邻的,如果是则将floor.start作为左区间,val作为右区间,将floor删除,然后在对第一个start>val的进行判断

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
class SummaryRanges {

    TreeSet<Interval> treeSet = null;

    /**
     * Initialize your data structure here.
     */
    public SummaryRanges() {

        // 内部的Interval对象按照区间的start进行排序
        treeSet = new TreeSet<>(new Comparator<Interval>() {
            @Override
            public int compare(Interval o1, Interval o2) {
                return o1.start - o2.start;
            }
        });
    }

    public void addNum(int val) {

        Interval interval = new Interval();
        interval.start = val;
        interval.end = val;

        // 从set中将第一个小于等于当前区间的数
        Interval floor = treeSet.floor(interval);

        // 从set中将第一个大于扥估当前区间的数拿出来
        Interval higher = treeSet.higher(interval);

        // 先判断能否与其左边的区间合并
        if(floor != null){

            // 说明这个区间已经被包含了
            if(floor.end >= val){

                return;
            }

            // 说明可以和小于val的区间进行合并
            if(floor.end + 1 == val){

                // 将floor删除,
                treeSet.remove(floor);
                interval.start = floor.start;
            }
        }

        if(higher != null){

            // 因为higher是第一个start>= val的,所以只需要判断是否相等即可判断是否是重叠区间
            if(higher.start == val){

                return;
            }

            // 如果val+1 == higher.start,说明val可以作为higher的左边界
            if(val + 1 == higher.start){

                treeSet.remove(higher);
                // 将interval作为higher的左边界
                interval.end = higher.end;
            }
        }

        treeSet.add(interval);
    }

    public List<Interval> getIntervals() {

        return Arrays.asList(treeSet.toArray(new Interval[]{}));
    }
}

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * List<Interval> param_2 = obj.getIntervals();
 */

猜你喜欢

转载自blog.csdn.net/zhttly/article/details/83281305