352. 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?

class SummaryRanges {
    // PriorityQueue<Integer> pq;
    List<Integer> list;
    
    /** Initialize your data structure here. */
    public SummaryRanges() {
        // pq = new PriorityQueue<>();
        list = new ArrayList();
        
    }
    
    public void addNum(int val) {
        // pq.offer(val);
        if(list.indexOf(val) < 0) list.add(val);
        Collections.sort(list);
//         for(int i = 0; i < list.size(); i++) {
            
//         }
    }
    
    public int[][] getIntervals() {
        // System.out.println(list.toString());
        List<int[]> res = new ArrayList();
        for(int i = 0; i < list.size(); i++) {
            int cur = i;
            while(cur+1 < list.size() && list.get(cur+1) - list.get(cur) == 1) cur++;
            if(cur != i) res.add(new int[]{list.get(i), list.get(cur)});
            else res.add(new int[]{list.get(i), list.get(i)});
            i = cur;
        }
        int[][] result = new int[res.size()][2];
        int j = 0;
        for(int[] tmp: res) result[j++] = tmp;
        return result;
    }
}

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * int[][] param_2 = obj.getIntervals();
 */

1. first ver

Used an arraylist to store unique values, sort after every add. Then generate interval array step by step.

class SummaryRanges {

        List<int[]> intervals;
        public SummaryRanges() {
            this.intervals = new ArrayList<>();
        }

        public void addNum(int val) {
            
            // flag: if there is an interval for val
            boolean noInterval = true;

            for (int i = 0; i < this.intervals.size(); i++){

                // if there is an overlap, break the loop and do nothing
                if (intervals.get(i)[0] <= val && intervals.get(i)[1] >= val){
                    noInterval = false;
                    break;
                }

                // change the interval; [1,2], val = 3 -> [1,3]
                if (intervals.get(i)[1] + 1 == val){
                    intervals.get(i)[1] = val;
                    noInterval = false;
                }

                // change the interval; [2,4], val = 3 -> [3,4]
                if (intervals.get(i)[0] - 1 == val){
                    intervals.get(i)[0] = val;
                    noInterval = false;
                }

                // check if we should merge two intervals;  [1,3], [3,4] - > [1,4]
                if (i != 0 && intervals.get(i - 1)[1] == intervals.get(i)[0]){
                    intervals.get(i)[0] = intervals.get(i - 1)[0];
                    intervals.get(i)[1] = intervals.get(i)[1];
                    intervals.remove(i - 1);
                }
            }

            // if there isnt an interval for val, add to the list.
            if (noInterval){
                intervals.add(new int[]{val, val});
            }
        }

        public int[][] getIntervals() {
            Collections.sort(intervals, (a, b) -> a[0]- b[0]);
            return intervals.toArray(new int[intervals.size()][]);
        }
    }

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * int[][] param_2 = obj.getIntervals();
 */

2.总结:

we just need to consider all situations, firstly we used the arraylist to store intervals.

In every add operation, we checked all situations:

  1. no overlap, which is intervals.get[i][0] <= val <= get(i)[1]

  2. [1,1], val = 2 whichi is intervals.get(i)[1] + 1 = val, we set intervals.get(i)[1] += 1 ---> [1, 2]

  3. [3, 3], val = 2, intervals.get(i)[0] - 1 = val, set intervals.get(i)[0] -= 1 ----> [2, 3]

  4. merge neighbor intervals, i != 0 && intervals.get(i - 1)[1] == intervals.get(i)[0], set intervals.get(i)[0] = intervals.get(i-1)[0], and remove i in map

in getIntervals, sort each interval by it's first value and get the result.

原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13364150.html