zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    BZOJ 1899: [Zjoi2004]Lunch 午餐
    BZOJ3670: [Noi2014]动物园
    BZOJ3712: [PA2014]Fiolki
    BZOJ1057: [ZJOI2007]棋盘制作
    BZOJ4326: NOIP2015 运输计划
    BZOJ4721: [Noip2016]蚯蚓
    BZOJ1131: [POI2008]Sta
    BZOJ1856: [Scoi2010]字符串
    BZOJ4003: [JLOI2015]城池攻占
    [AH2017/HNOI2017]单旋
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13364150.html
Copyright © 2011-2022 走看看