其他题目---一种消息接受并打印的结构设计

来源:互联网 发布:宏观研究知乎 编辑:程序博客网 时间:2024/06/05 20:15

【题目】

  消息流吐出2,一种结构接收而不打印2,因为1还没出现。
  消息流吐出1,一种结构接收1,并且打印:1,2。
  消息流吐出4,一种结构接收而不打印4,因为3还没有出现。
  消息流吐出5,一种结构接收而不打印5,因为3还没有出现。
  消息流吐出7,一种结构接收而不打印7,因为3还没有出现。
  消息流吐出3,一种结构接收3,并且打印:3,4,5。
  消息流吐出9,一种结构接收而不打印9,因为6还没出现。
  消息流吐出8,一种结构接收而不打印8,因为6还没出现。
  消息流吐出6,一种结构接收6,并且打印:6,7,8,9。
  已知一个消息流会不断地吐出整数1~N,但不一定按照顺序吐出。如果上次打印的数为i,那么当i+1出现是,请打印i+1及其之后接收过的并且连续的所有数,直到1~N全部接收并且打印完,请设计这种接收并打印的结构。

【要求】

  消息流最终会吐出全部的1~N,当然最终也会打印完所有的1~N,要求接收和打印1~N的整个过程,时间复杂度为O(N)。

【基本思路】

  对于接收的每一个数,如果能和之前接收的数连续起来,就归入之前的数据区间中,如果不能就单独成为一个区间。每一个区间使用单链表结构实现。

  例如,接收2的时候,根据2生成一个单链表节点,因为没有其他元素,所以它单独成一个区间[2];接收1的时候,根据1生成一个节点,然后发现之前的区间[2]可以和1连续起来,所以将该节点归入区间[2],此时该区间更新为[1,2];接收4的时候,根据4生成一个节点,没有区间可以和它连续起来,所以它单独成一个区间[4];然后接收5,和4连续起来,[4]区间更新为[4,5];然后接收3,3可以和[1,2]连续起来,也可以和[4,5]连续起来,所有整体可以归入一个区间[1~5]。

  为了加速合并的过程,使用两个哈希表headMap和tailMap,分别用来存放区间的开头节点和结尾节点。假设一个数n被接收,首先将n的节点添加到headMap和tailMap中。然后在headMap中寻找是否有n+1元素,如果有,说明以n+1开头的区间可以向左再添加一个数n,所以将区间扩充1位,将headMap中的n+1元素和tailMap中的n元素删除。然后在tailMap中寻找是否有n-1元素,如果有,说明以n-1结尾的区间可以向右再添加一个数n,所以将区间扩充1位,将tailMap中的n-1元素和headMap中的n元素删除。

  什么时候打印呢?设置一个变量lastPrint,表示上一次打印的最后一个元素是什么,然后每次在headMap中寻找是否有lastPrint+1元素,如果有的话,将整个以lastPrint+1开头的区间的数都打印,然后更新lastPrint。

【代码实现】

#python3.5class Node2:    def __init__(self, value):        self.value = value        self.next = Noneclass MessageBox:    def __init__(self):        self.headMap = {}        self.tailMap = {}        self.lastPrint = 0    def receive(self, value):        node = Node(value)        self.headMap[value] = node        self.tailMap[value] = node        if value + 1 in self.headMap:            node.next = self.headMap[value+1]            del self.headMap[value+1]            del self.tailMap[value]        if value - 1 in self.tailMap:            self.tailMap[value-1].next = node            del self.tailMap[value-1]            del self.headMap[value]        if self.lastPrint + 1 in self.headMap:            self.printValue()    def printValue(self):        head = self.headMap[self.lastPrint+1]        del self.headMap[self.lastPrint+1]        while head != None:            print(head.value, end=' ')            head = head.next            self.lastPrint += 1        del self.tailMap[self.lastPrint]