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?

 

Approach #1: C++.

/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class SummaryRanges {
private:
vector<Interval> intervals = vector<Interval>(); int binarySearch(vector<Interval> intervals, int val) {
return binarySearchHelper(intervals, 0, intervals.size(), val);
} int binarySearchHelper(vector<Interval> intervals, int start, int end, int val) {
if (start == end) return -1;
if (start+1 == end && intervals[start].start < val) return start; int mid = (start + end) / 2; if (intervals[mid].start == val) return mid;
else if (intervals[mid].start < val)
return binarySearchHelper(intervals, mid, end, val);
else
return binarySearchHelper(intervals, start, mid, val);
} public:
/** Initialize your data structure here. */
SummaryRanges() { } void addNum(int val) {
int index = binarySearch(intervals, val);
if (index != -1 && intervals[index].end >= val)
return; if (index != intervals.size() - 1 && val + 1 == intervals[index+1].start)
intervals[index+1].start = val;
else if (index != -1 && val - 1 == intervals[index].end)
intervals[index].end = val;
else {
intervals.insert(intervals.begin()+index+1, Interval(val, val));
} if (index != -1 && intervals[index].end + 1 == intervals[index+1].start) {
intervals[index].end = intervals[index+1].end;
intervals.erase(intervals.begin()+index+1);
} return ;
} vector<Interval> getIntervals() {
return this->intervals;
}
}; /**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* vector<Interval> param_2 = obj.getIntervals();
*/

  

Approach #2: Java.

/**
* 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 {
TreeMap<Integer, Interval> tree; /** Initialize your data structure here. */
public SummaryRanges() {
tree = new TreeMap<>();
} public void addNum(int val) {
if (tree.containsKey(val)) return ;
Integer l = tree.lowerKey(val);
Integer h = tree.higherKey(val);
if (l != null && h != null && tree.get(l).end + 1 == val && h == val + 1) {
tree.get(l).end = tree.get(h).end;
tree.remove(h);
} else if (l != null && tree.get(l).end + 1 >= val) {
tree.get(l).end = Math.max(tree.get(l).end, val);
} else if (h != null && h == val + 1) {
tree.put(val, new Interval(val, tree.get(h).end));
tree.remove(h);
} else {
tree.put(val, new Interval(val, val));
}
} public List<Interval> getIntervals() {
return new ArrayList<>(tree.values());
}
} /**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* List<Interval> param_2 = obj.getIntervals();
*/

  

Appraoch #3: Python.

# Definition for an interval.
# class Interval(object):
# def __init__(self, s=0, e=0):
# self.start = s
# self.end = e class SummaryRanges(object): def __init__(self):
"""
Initialize your data structure here.
"""
self.intervals = [] def addNum(self, val):
"""
:type val: int
:rtype: void
"""
heapq.heappush(self.intervals, (val, Interval(val, val))) def getIntervals(self):
"""
:rtype: List[Interval]
"""
stack = []
while self.intervals:
idx, cur = heapq.heappop(self.intervals)
if not stack:
stack.append((idx, cur))
else:
_, prev = stack[-1]
if prev.end + 1 >= cur.start:
prev.end = max(prev.end, cur.end)
else:
stack.append((idx, cur))
self.intervals = stack
return list(map(lambda x : x[1], stack)) # Your SummaryRanges object will be instantiated and called as such:
# obj = SummaryRanges()
# obj.addNum(val)
# param_2 = obj.getIntervals()

  

Note:

Java -----> Treemap.

Class TreeMap<K,V>

  • Type Parameters:
    K - the type of keys maintained by this map
    V - the type of mapped values
    All Implemented Interfaces:
    SerializableCloneableMap<K,V>, NavigableMap<K,V>, SortedMap<K,V>

    public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, Serializable
    A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

    This implementation provides guaranteed log(n) time cost for the containsKeygetput and remove operations. Algorithms are adaptations of those in Cormen, Leiserson, and Rivest's Introduction to Algorithms.

    Note that the ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with equals if this sorted map is to correctly implement the Map interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, but a sorted map performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a sorted map is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Map interface.

    Note that this implementation is not synchronized. If multiple threads access a map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with an existing key is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedSortedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:

       SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));

    The iterators returned by the iterator method of the collections returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

    Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

    All Map.Entry pairs returned by methods in this class and its views represent snapshots of mappings at the time they were produced. They do not support the Entry.setValue method. (Note however that it is possible to change mappings in the associated map using put.)

Python -----> lambda.

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

通过对比可以看出,匿名函数lambda x: x * x实际上就是:

def f(x):
return x * x

关键字lambda表示匿名函数,冒号前面的x表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25

同样,也可以把匿名函数作为返回值返回,比如:

def build(x, y):
return lambda: x * x + y * y

 

Python -----> heapq.

This module provides an implementation of the heap queue algorithm, also known as the priority queue algorithm.

Heaps are arrays for which heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2] for all k, counting elements from zero. For the sake of comparison, non-existing elements are considered to be infinite. The interesting property of a heap is that heap[0] is always its smallest element.

The API below differs from textbook heap algorithms in two aspects: (a) We use zero-based indexing. This makes the relationship between the index for a node and the indexes for its children slightly less obvious, but is more suitable since Python uses zero-based indexing. (b) Our pop method returns the smallest item, not the largest (called a “min heap” in textbooks; a “max heap” is more common in texts because of its suitability for in-place sorting).

These two make it possible to view the heap as a regular Python list without surprises: heap[0] is the smallest item, and heap.sort() maintains the heap invariant!

To create a heap, use a list initialized to [], or you can transform a populated list into a heap via function heapify().

352. Data Stream as Disjoint Intervals (TreeMap, lambda, heapq)的更多相关文章

  1. 352. Data Stream as Disjoint Intervals

    Plz take my miserable life T T. 和57 insert interval一样的,只不过insert好多. 可以直接用57的做法一个一个加,然后如果数据大的话,要用tree ...

  2. [LeetCode] 352. Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  3. leetcode@ [352] Data Stream as Disjoint Intervals (Binary Search & TreeSet)

    https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of non-ne ...

  4. 【leetcode】352. Data Stream as Disjoint Intervals

    问题描述: Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers ...

  5. [leetcode]352. Data Stream as Disjoint Intervals

    数据流合并成区间,每次新来一个数,表示成一个区间,然后在已经保存的区间中进行二分查找,最后结果有3种,插入头部,尾部,中间,插入头部,不管插入哪里,都判断一下左边和右边是否能和当前的数字接起来,我这样 ...

  6. Leetcode: Data Stream as Disjoint Intervals && Summary of TreeMap

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  7. 352[LeetCode] Data Stream as Disjoint Intervals

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  8. [LeetCode] Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  9. 352. Data Stream as Disjoint Interval

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

随机推荐

  1. 《Linux 鸟哥私房菜》 第一部分 Linux文件、目录与磁盘格式

    1.Linux就是内核层与系统调用接口层这2层.

  2. ubuntu 下解决sublime v3 中文输入法时 退格键删除不了拼音的问题

    ubuntu下,sulime想要支持中文需要这样设置: 1.安装中文输入解决的github git clone https://github.com/lyfeyaj/sublime-text-imfi ...

  3. 题解 P1387 【最大正方形】

    传送门 搞不清楚为什么这一题要DP . . . . . . 思路: \(n\le100\),考虑暴力. 要求一大块区间内都是1,考虑前缀和. 在矩阵中求一个符合条件的子矩阵,考虑\(n^3\)的&qu ...

  4. X86/X64处理器体系结构及寻址模式

    由8086/8088.x86.Pentium发展到core系列短短40多年间,处理器的时钟频率差点儿已接近极限.尽管如此,自从86年Intel推出386至今除了添加一些有关流媒体的指令如mmx/sse ...

  5. 用c++后缀自动机实现最大公共字符串算法,并封装成Python库

    后缀自动机的C++代码转自https://e-maxx.ru/algo/suffix_automata,其余封装为自写. 在C++文件同级目录建立setup.py文件,代码如下: # !/usr/bi ...

  6. Java for LeetCode 083 Remove Duplicates from Sorted List

    Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...

  7. STemWin显示汉字 — SD卡外挂XBF字库

    转载注明出处  方法来自安福莱教程 1: 使用emWin自带小工具生成字库 (1)启动软件 选择4位抗锯齿 (2)根据需求选择字体类型和字体大小 (3)另存为XBF格式 2: 创建XBF字体 #inc ...

  8. html-webpack-plugin 中使用 title选项设置模版中的值无效

    原文地址:https://segmentfault.com/q/1010000004555431 webpack.config.js配置: var webpack = require("we ...

  9. Ubuntu 17.4下如何安装和配置flash player

    Ubuntu Linux系统下没有自带的flash player,要自己手动安装.下面post出简单的安装过程. 首先打开终端,输入命令:sudo apt-get install flashplugi ...

  10. 迁移学习——使用Tensorflow和VGG16预训模型进行预测

    使用Tensorflow和VGG16预训模型进行预测 from:https://zhuanlan.zhihu.com/p/28997549   fast.ai的入门教程中使用了kaggle: dogs ...