leetcode@ [352] Data Stream as Disjoint Intervals (Binary Search & TreeSet)
https://leetcode.com/problems/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]
Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?
/** * 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 cmp implements Comparator { public int compare(Object o1, Object o2) { Interval i1 = (Interval) o1; Interval i2 = (Interval) o2; if(i1.start < i2.start) { return -1; } else if(i1.start == i2.start) { if(i1.end == i2.end) { return 0; } else if(i1.end < i2.end) { return -1; } else { return 1; } } else { return 1; } } } public class SummaryRanges { public Set<Interval> interval_pool = null; /** Initialize your data structure here. */ public SummaryRanges() { interval_pool = new TreeSet<Interval> (new cmp()); } public boolean binarySearch(Object[] ls, int key) { int l = 0, r = ls.length-1; while(l <= r) { int mid = (l + r) / 2; Interval it = (Interval) ls[mid]; if(key <= it.end && key >= it.start) { return true; } else if(key > it.end) { l = mid+1; } else { r = mid-1; } } return false; } public Interval leftAdjacent(Object[] ls, int key) { int l = 0, r = ls.length-1; while(l <= r) { int mid = (l + r) / 2; Interval it = (Interval) ls[mid]; if(key == it.end) { return it; } else if(key > it.start) { l = mid+1; } else { r = mid-1; } } return null; } public Interval rightAdjacent(Object[] ls, int key) { int l = 0, r = ls.length-1; while(l <= r) { int mid = (l + r) / 2; Interval it = (Interval) ls[mid]; if(key == it.start) { return it; } else if(key > it.start) { l = mid+1; } else { r = mid-1; } } return null; } public void addNum(int val) { if(interval_pool.size() == 0) { interval_pool.add(new Interval(val, val)); return; } Object[] ls = interval_pool.toArray(); boolean in = binarySearch(ls, val); if(!in) { int start = val, end = val; Interval l_adj = leftAdjacent(ls, val-1); Interval r_adj = rightAdjacent(ls, val+1); if(l_adj != null) { start = l_adj.start; interval_pool.remove(l_adj); } if(r_adj != null) { end = r_adj.end; interval_pool.remove(r_adj); } Interval it = new Interval(start, end); interval_pool.add(it); } } public List<Interval> getIntervals() { List<Interval> rs = new ArrayList<Interval> (); Object[] ls = interval_pool.toArray(); for(int i=0; i<ls.length; ++i) { Interval it = (Interval) ls[i]; rs.add(it); } return rs; } } /** * Your SummaryRanges object will be instantiated and called as such: * SummaryRanges obj = new SummaryRanges(); * obj.addNum(val); * List<Interval> param_2 = obj.getIntervals(); */