LeetCode 352. Data Stream as Disjoint Intervals(数据流区间)

来源:互联网 发布:网络星期一 2015 编辑:程序博客网 时间:2024/05/19 02:06

原题网址: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?

方法一:使用集合保存到目前为止的数据集,插入时间O(1),读取时间O(N)

/** * 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; } * } */public class SummaryRanges {    private Set<Integer> set = new HashSet<>();    /** Initialize your data structure here. */    public SummaryRanges() {            }        public void addNum(int val) {        set.add(val);    }        public List<Interval> getIntervals() {        Set<Integer> s = new HashSet<>(set);        List<Interval> list = new ArrayList<>();        while (!s.isEmpty()) {            int min = s.iterator().next();            int max = min;            s.remove(min);            for(int i=max+1;;i++) {                if (s.remove(i)) max = i;                else break;            }            for(int i=min-1;; i--) {                if (s.remove(i)) min = i;                else break;            }            list.add(new Interval(min, max));        }        Collections.sort(list, new Comparator<Interval>() {            @Override            public int compare(Interval i1, Interval i2) {                return i1.start - i2.start;            }        });        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(); */

方法二:使用二分法查找区间,插入时间O(logN),读取时间O(1)。

/** * 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; } * } */public class SummaryRanges {    private List<Interval> list = new ArrayList<>();        /** Initialize your data structure here. */    public SummaryRanges() {            }        public void addNum(int val) {        if (list.isEmpty()) {            list.add(new Interval(val, val));            return;        }        int i=0, j=list.size()-1;        while (i<=j) {            int m = (i+j)/2;            Interval interval = list.get(m);            if (interval.start <= val && val <= interval.end) return;            if (val > interval.start) i=m+1; else j=m-1;        }                Interval target = i == list.size() ? null : list.get(i);        Interval left = i == 0 ? null : list.get(i-1);        if (i == 0) {            if (val+1 == target.start) {                target.start = val;                return;            }            list.add(0, new Interval(val, val));            return;        } else if (i==list.size()) {            if (left.start <= val && val <= left.end) return;            if (left.end+1 == val) {                left.end = val;                return;            }            list.add(new Interval(val, val));            return;        } else {            if (target.start <= val && val <= target.end) return;            if (left.start <= val && val <= left.end) return;            if (left.end+1 < val && val+1 < target.start) {                list.add(i, new Interval(val, val));                return;            }            if (left.end+1 == val) {                left.end = val;            }            if (val+1 == target.start) {                target.start = val;            }            if (left.end == target.start) {                left.end = target.end;                list.remove(i);            }        }    }        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(); */

0 0
原创粉丝点击