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]
Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?
返回区间,将连续增长的区间合并。
比较直接的一种思路,就是记录当前的数字,每次插入新的数字后,将所有数字进行升序排序,再合并区间,时间复杂度为nlong(n),程序如下所示:
/**
* 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 {
List<Integer> list;
List<Interval> l;
Set<Integer> set;
/** Initialize your data structure here. */
public SummaryRanges() {
list = new ArrayList<>();
set = new HashSet<>();
}
public void addNum(int val) {
if (set.contains(val)){
return ;
}
set.add(val);
list.add(val);
Collections.sort(list);
int start = list.get(0);
l = new ArrayList<>();
for (int i = 1; i < list.size(); ++ i){
if (list.size() == 1||list.get(i) != (list.get(i-1) + 1)){
l.add(new Interval(start, list.get(i-1)));
start = list.get(i);
}
}
l.add(new Interval(start, list.get(list.size() - 1)));
}
public List<Interval> getIntervals() {
return l;
}
}
/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* List<Interval> param_2 = obj.getIntervals();
*/
本例也可用一颗二叉搜索树来表示插入的数据,调用addNum函数时,先将数据插入二叉查找树,复杂度为O(n),在对而查找树进行遍历,生成返回的区间间隔,时间复杂度也为O(n),因此,通过一颗二叉查找树管理插入的数据,时间复杂度会比上述给出的程序要低。