题目描述
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();
*/