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

    Credits:
    Special thanks to @yunhong for adding this problem and creating most of the test cases.

    Solution 1:

     1 /**
     2  * Definition for an interval.
     3  * public class Interval {
     4  *     int start;
     5  *     int end;
     6  *     Interval() { start = 0; end = 0; }
     7  *     Interval(int s, int e) { start = s; end = e; }
     8  * }
     9  */
    10 public class SummaryRanges {
    11 
    12    /** Initialize your data structure here. */
    13         public SummaryRanges() {
    14             startMap = new HashMap<Integer, Interval>();
    15             endMap = new HashMap<Integer, Interval>();
    16             addedNum = new HashSet<Integer>();
    17         }
    18 
    19         public void addNum(int val) {
    20             if (addedNum.contains(val)) return;
    21             
    22             Interval pre = null, after = null;
    23             if (endMap.containsKey(val - 1))
    24                 pre = endMap.get(val - 1);
    25             if (startMap.containsKey(val + 1))
    26                 after = startMap.get(val + 1);
    27 
    28             if (pre != null && after != null) {
    29                 endMap.remove(after.end);                
    30                 startMap.remove(after.start);
    31                 endMap.remove(pre.end);
    32                 pre.end = after.end;
    33                 endMap.put(pre.end, pre);
    34             } else if (pre != null) {
    35                 endMap.remove(pre.end);
    36                 pre.end = val;
    37                 endMap.put(val, pre);
    38             } else if (after != null) {
    39                 startMap.remove(after.start);
    40                 after.start = val;
    41                 startMap.put(val, after);
    42             } else {
    43                 Interval single = new Interval(val, val);
    44                 endMap.put(val, single);
    45                 startMap.put(val, single);
    46             }
    47             
    48             addedNum.add(val);
    49         }
    50 
    51         public List<Interval> getIntervals() {
    52             List<Interval> intervalList = new ArrayList<Interval>(endMap.values());
    53             Collections.sort(intervalList, new Comparator<Interval>() {
    54                 public int compare(Interval v1, Interval v2) {
    55                     return v1.start - v2.start;
    56                 }
    57             });
    58             return intervalList;
    59         }
    60 
    61         HashMap<Integer, Interval> startMap;
    62         HashMap<Integer, Interval> endMap;
    63         HashSet<Integer> addedNum;
    64 }
    65 
    66 /**
    67  * Your SummaryRanges object will be instantiated and called as such:
    68  * SummaryRanges obj = new SummaryRanges();
    69  * obj.addNum(val);
    70  * List<Interval> param_2 = obj.getIntervals();
    71  */

    This solution introduces many redundant: To find the "pre", we only need to find the interval with the largest start that is less than val. In short, we only need to compare Interval.start

    Solution 2:

     1 /**
     2  * Definition for an interval.
     3  * public class Interval {
     4  *     int start;
     5  *     int end;
     6  *     Interval() { start = 0; end = 0; }
     7  *     Interval(int s, int e) { start = s; end = e; }
     8  * }
     9  */
    10 public class SummaryRanges {
    11 
    12     /** Initialize your data structure here. */
    13     public SummaryRanges() {
    14         itvlSet = new TreeSet<Interval>(new Comparator<Interval>(){
    15             public int compare(Interval v1, Interval v2){
    16                 return v1.start-v2.start;
    17             }
    18         });
    19         
    20     }
    21     
    22     public void addNum(int val) {
    23         Interval itvl = new Interval(val,val);
    24         Interval pre = itvlSet.floor(itvl);
    25         Interval after = itvlSet.ceiling(itvl);
    26         
    27         if ( (pre!=null && pre.end >= val) || (after!=null && after.start <=val)) return;
    28         
    29         if (pre!=null && pre.end==val-1){
    30             itvlSet.remove(pre);
    31             itvl.start = pre.start;
    32         }
    33         if (after!=null && after.start==val+1){
    34             itvlSet.remove(after);
    35             itvl.end = after.end;
    36         }
    37         itvlSet.add(itvl);
    38     }
    39     
    40     public List<Interval> getIntervals() {
    41         return new ArrayList<Interval>(itvlSet);
    42         
    43     }
    44     
    45     TreeSet<Interval> itvlSet;
    46 }
    47 
    48 /**
    49  * Your SummaryRanges object will be instantiated and called as such:
    50  * SummaryRanges obj = new SummaryRanges();
    51  * obj.addNum(val);
    52  * List<Interval> param_2 = obj.getIntervals();
    53  */
  • 相关阅读:
    使用集合组织相关数据
    深入类的方法
    深入C#数据类型
    上机练习1 更新会员积分
    魔兽争霸登录
    jQuery
    打卡系统
    [工具]kalilinux2016.2 更新后
    [技术分享]借用UAC完成的提权思路分享
    [技术分享]利用MSBuild制作msf免杀的后门
  • 原文地址:https://www.cnblogs.com/lishiblog/p/5688275.html
Copyright © 2011-2022 走看看