# 352 Data Stream as Disjoint Intervals

data stream input皆為正整數,將input data stream用數字區間表示。

例如:data stream input=[1,3,7,2,6] 可以表示為:[1,3] [6,7]

提供資料結構如下

/**
 * 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 {

    /** Initialize your data structure here. */
    public SummaryRanges() {

    }

    public void addNum(int val) {

    }

    public List<Interval> getIntervals() {

    }
}

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * List<Interval> param_2 = obj.getIntervals();
 */

Idea 用list來存數字區間,getInterval()就return list。 addNum(): 將list用interval.start遞增排序,在list中找到第一個start比val大的數字區間,將index設在該位置。若前一個數字區間有合併的可能,則將index往前移一個位置。 用一while迴圈檢查index i的數字區間是否可以和val合併,若可以,更新start, end,並把該區間移除。 離開while迴圈後,將[start, end] 區間插入index i。

Code

/**
 * 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<Interval> list;
    /** Initialize your data structure here. */
    public SummaryRanges() {
        list = new ArrayList<>();
    }

    public void addNum(int val){
        Collections.sort(list, new Comparator<Interval>() {
            @Override
            public int compare(Interval a, Interval b) {
                return a.start < b.start ? -1 : 1;
            }
        });

        int start = val, end = val;
        int i=0;
        if(list.size() > 0){
            Interval cur = list.get(0);
            while(val > cur.start && ++i < list.size()){
                cur = list.get(i);
            }
            if(i != 0 && list.get(i-1).end+1 >= val) i--;
        }

        while(i < list.size() && val+1 >= list.get(i).start && val-1 <= list.get(i).end){
            start = Math.min(start, list.get(i).start);
            end = Math.max(end, list.get(i).end);
            list.remove(i);
        }

        if(i >= list.size()){
            list.add(new Interval(start,end));
        }else{
            list.add(i, new Interval(start,end));
        }

    }  

    public List<Interval> getIntervals() {
        return list;
    }
}

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * List<Interval> param_2 = obj.getIntervals();
 */

Followup Q: What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size? A: 用list存時,搜尋區間的時間複雜度為O(N),若改用binary search tree存,可以減少到O(logN)

results matching ""

    No results matching ""