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]
  2. [1, 1], [3, 3]
  3. [1, 1], [3, 3], [7, 7]
  4. [1, 3], [7, 7]
  5. [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++.

  1. /**
  2. * Definition for an interval.
  3. * struct 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. class SummaryRanges {
  11. private:
  12. vector<Interval> intervals = vector<Interval>();
  13.  
  14. int binarySearch(vector<Interval> intervals, int val) {
  15. return binarySearchHelper(intervals, 0, intervals.size(), val);
  16. }
  17.  
  18. int binarySearchHelper(vector<Interval> intervals, int start, int end, int val) {
  19. if (start == end) return -1;
  20. if (start+1 == end && intervals[start].start < val) return start;
  21.  
  22. int mid = (start + end) / 2;
  23.  
  24. if (intervals[mid].start == val) return mid;
  25. else if (intervals[mid].start < val)
  26. return binarySearchHelper(intervals, mid, end, val);
  27. else
  28. return binarySearchHelper(intervals, start, mid, val);
  29. }
  30.  
  31. public:
  32. /** Initialize your data structure here. */
  33. SummaryRanges() {
  34.  
  35. }
  36.  
  37. void addNum(int val) {
  38. int index = binarySearch(intervals, val);
  39. if (index != -1 && intervals[index].end >= val)
  40. return;
  41.  
  42. if (index != intervals.size() - 1 && val + 1 == intervals[index+1].start)
  43. intervals[index+1].start = val;
  44. else if (index != -1 && val - 1 == intervals[index].end)
  45. intervals[index].end = val;
  46. else {
  47. intervals.insert(intervals.begin()+index+1, Interval(val, val));
  48. }
  49.  
  50. if (index != -1 && intervals[index].end + 1 == intervals[index+1].start) {
  51. intervals[index].end = intervals[index+1].end;
  52. intervals.erase(intervals.begin()+index+1);
  53. }
  54.  
  55. return ;
  56. }
  57.  
  58. vector<Interval> getIntervals() {
  59. return this->intervals;
  60. }
  61. };
  62.  
  63. /**
  64. * Your SummaryRanges object will be instantiated and called as such:
  65. * SummaryRanges obj = new SummaryRanges();
  66. * obj.addNum(val);
  67. * vector<Interval> param_2 = obj.getIntervals();
  68. */

  

Approach #2: Java.

  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. class SummaryRanges {
  11. TreeMap<Integer, Interval> tree;
  12.  
  13. /** Initialize your data structure here. */
  14. public SummaryRanges() {
  15. tree = new TreeMap<>();
  16. }
  17.  
  18. public void addNum(int val) {
  19. if (tree.containsKey(val)) return ;
  20. Integer l = tree.lowerKey(val);
  21. Integer h = tree.higherKey(val);
  22. if (l != null && h != null && tree.get(l).end + 1 == val && h == val + 1) {
  23. tree.get(l).end = tree.get(h).end;
  24. tree.remove(h);
  25. } else if (l != null && tree.get(l).end + 1 >= val) {
  26. tree.get(l).end = Math.max(tree.get(l).end, val);
  27. } else if (h != null && h == val + 1) {
  28. tree.put(val, new Interval(val, tree.get(h).end));
  29. tree.remove(h);
  30. } else {
  31. tree.put(val, new Interval(val, val));
  32. }
  33. }
  34.  
  35. public List<Interval> getIntervals() {
  36. return new ArrayList<>(tree.values());
  37. }
  38. }
  39.  
  40. /**
  41. * Your SummaryRanges object will be instantiated and called as such:
  42. * SummaryRanges obj = new SummaryRanges();
  43. * obj.addNum(val);
  44. * List<Interval> param_2 = obj.getIntervals();
  45. */

  

Appraoch #3: Python.

  1. # Definition for an interval.
  2. # class Interval(object):
  3. # def __init__(self, s=0, e=0):
  4. # self.start = s
  5. # self.end = e
  6.  
  7. class SummaryRanges(object):
  8.  
  9. def __init__(self):
  10. """
  11. Initialize your data structure here.
  12. """
  13. self.intervals = []
  14.  
  15. def addNum(self, val):
  16. """
  17. :type val: int
  18. :rtype: void
  19. """
  20. heapq.heappush(self.intervals, (val, Interval(val, val)))
  21.  
  22. def getIntervals(self):
  23. """
  24. :rtype: List[Interval]
  25. """
  26. stack = []
  27. while self.intervals:
  28. idx, cur = heapq.heappop(self.intervals)
  29. if not stack:
  30. stack.append((idx, cur))
  31. else:
  32. _, prev = stack[-1]
  33. if prev.end + 1 >= cur.start:
  34. prev.end = max(prev.end, cur.end)
  35. else:
  36. stack.append((idx, cur))
  37. self.intervals = stack
  38. return list(map(lambda x : x[1], stack))
  39.  
  40. # Your SummaryRanges object will be instantiated and called as such:
  41. # obj = SummaryRanges()
  42. # obj.addNum(val)
  43. # 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>

    1. public class TreeMap<K,V>
    2. extends AbstractMap<K,V>
    3. 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:

    1. 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)的函数外,还可以直接传入匿名函数:

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

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

  1. def f(x):
  2. return x * x

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

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

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

  1. >>> f = lambda x: x * x
  2. >>> f
  3. <function <lambda> at 0x101c6ef28>
  4. >>> f(5)
  5. 25

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

  1. def build(x, y):
  2. 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. 我的Android进阶之旅------>Android图片处理(Matrix,ColorMatrix)

    本文转载于:http://www.cnblogs.com/leon19870907/articles/1978065.html 在编程中有时候需要对图片做特殊的处理,比如将图片做出黑白的,或者老照片的 ...

  2. SpringBoot学习笔记(13):日志框架

    SpringBoot学习笔记(13):日志框架——SL4J 快速开始 说明 SpringBoot底层选用SLF4J和LogBack日志框架. SLF4J的使用 SpringBoot的底层依赖关系 1. ...

  3. Ubuntu/CentOS下使用脚本自动安装 Docker

    Ubuntu.Debian 系列安装 Docker 系统要求 Docker 支持以下版本的 Ubuntu 和 Debian 操作系统: Ubuntu Xenial 16.04 (LTS) Ubuntu ...

  4. 一次react滚动列表的实践---兼容ios安卓

    一.背景 近期项目改版,对原有的h5页面进行了重新设计,数据呈现变成了瀑布流.希望新版兼容ios和安卓两端的情况下,无限制的刷新加载数据.大致效果如下: 整个页面分4部分: 顶部导航 步数状态卡片 用 ...

  5. git设置只允许特定类型的文件

    git设置只允许特定类型的文件 # 忽略所有文件 * # 不忽略目录 !*/ # 不忽略文件.gitignore和*.foo !.gitignore !*.foo

  6. [BZOJ4557][JLOI2016]侦查守卫

    4557: [JLoi2016]侦察守卫 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 297  Solved: 200[Submit][Status ...

  7. SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串

    题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags  You ...

  8. 1.1 BASIC PROGRAMMING MODEL(算法 Algorithms 第4版)

    1.1.1 private static void exercise111() { StdOut.println("1.1.1:"); StdOut.println((0+15)/ ...

  9. Mysql转换表存储引擎的三种方式

    或许会有一些场景需要改变表的存储引擎,例如存储日志的表如果几乎只有insert和少量的select操作,为了追求更好的插入性能有可能会需要把存储引擎更换为MyISAM.但是,本文不建议在同一个数据库中 ...

  10. BZOJ 1637 [Usaco2007 Mar]Balanced Lineup:前缀和 + 差分

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1637 题意: Farmer John 决定给他的奶牛们照一张合影,他让 N (1 ≤ N ...