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

【题目】

  消息流吐出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.5
class Node2:
    def __init__(self, value):
        self.value = value
        self.next = None

class 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]
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值