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?
思路:乍一看感觉是要用二分查找的,但是有Interval归并的情况,数组貌似行不通,想用tree来做,刚开始还打算自己写个Node节点类,把Interval封装到Node来做,后来才发现完全不必要,TreeMap已经为我们封装好了
需要注意的是:不能修改Interval中的start,因为它是与Key进行绑定的,而Key是不可变的
/**
* 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; }
* }
*/
import java.util.*;
public class SummaryRanges {
TreeMap<Integer, Interval> tree = new TreeMap<Integer, Interval>();
/** Initialize your data structure here. */
public SummaryRanges() {
}
public void addNum(int val) {
if(tree.containsKey(val)) return;
if(tree.size() == 0) tree.put(val, new Interval(val, val));
Integer l = tree.lowerKey(val);
Integer h = tree.higherKey(val);
if(l == null) {
Interval newInterval = new Interval(val, val);
tree.put(val, newInterval);
if(h!=null && val+1 == tree.get(h).start) {
newInterval.end = tree.get(h).end;
tree.remove(h);
}
} else {
if(tree.get(l).end >= val)
return;
else if(tree.get(l).end+1 == val) {
tree.get(l).end++;
if(h!=null && val+1 == tree.get(h).start) {
tree.get(l).end = tree.get(h).end;
tree.remove(h);
}
} else {
Interval newInterval = new Interval(val, val);
tree.put(val, newInterval);
if(h!=null && val+1 == tree.get(h).start) {
newInterval.end = tree.get(h).end;
tree.remove(h);
}
}
}
}
public List<Interval> getIntervals() {
return new ArrayList<Interval>(tree.values());
}
}
/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* List<Interval> param_2 = obj.getIntervals();
*/
代码丑死了,重新写了一下,addNum不就4种情况嘛:
1. 只是更新lowerKey的end
2. 更新lowerKey的end,并合并了higherKey
3. 只是添加了一个新的节点
4. 添加了节点,并与higherKey合并
/**
* 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; }
* }
*/
import java.util.*;
public class SummaryRanges {
TreeMap<Integer, Interval> tree = new TreeMap<Integer, Interval>();
/** Initialize your data structure here. */
public SummaryRanges() {
}
public void addNum(int val) {
if(tree.containsKey(val)) return;
Integer l = tree.lowerKey(val);
Integer h = tree.higherKey(val);
if(l!=null && h!=null && tree.get(l).end+1==val && val+1==h) {
tree.get(l).end = tree.get(h).end;
tree.remove(h);
} else if(l!=null && val<=tree.get(l).end+1) {
if(tree.get(l).end<val) tree.get(l).end=val;
} else if(h!=null && h==val+1) {
tree.put(val, new Interval(val, tree.get(h).end));
tree.remove(h);
} else {
tree.put(val, new Interval(val, val));
}
}
public List<Interval> getIntervals() {
return new ArrayList<Interval>(tree.values());
}
}
/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* List<Interval> param_2 = obj.getIntervals();
*/