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();
 */
View Code

 

posted @ 2016-06-29 21:26  流白  阅读(163)  评论(0编辑  收藏  举报