前几天面试算法岗遇到这样一道题目:给定一个实时的数据流,分别是员工ID,员工入职时间或者时员工离职时间,要求设计函数返回当时在公司工作时间最长的员工ID。
因为我做题太少的原因,当时针对这一题很多没搞清楚,在回学校仔细思考后,给出下面的解答,并以此为戒,多做题!!!!
首先最简单的思路是用单向链表存储仍在公司的员工,而对于已经离职的员工,我们只需要知道当前离职的工作时间最长的那一位员工就可以了,因此每次求仍在公司的员工的最大工作时间以及ID,是一个O(N)复杂度的问题。
可以考虑采用哈希表加双向链表的结构将这个问题变为O(1)复杂度,每次有员工入职时,添加员工信息节点至双向链表末尾,并将这个节点存储在字典中以便查找,每次有员工离职时,根据字典查找删除该节点,并将它两端的节点相互连接,每次需要返回最长工作时间员工时,则取出链表头部员工信息代表仍在公司的、工作时间最长的员工。
具体代码如下
1 #给定数据流员工ID,入职时间或者是离职时间,设计函数求出当前在公司工作时间最长的员工ID 2 #要点1:离职员工只需要考虑在本公司工作最长的一个员工即可 3 #要点2:仍在本公司的员工应利用dict作为哈希表,用于储存由仍在公司员工信息所构成的双向链表,从而使查询时间变为O(1) 4 #要点3:注意python对于可变对象的浅层复制 5 #要点4:要明确这道题的input是单个时间,而不是一个list 6 class chain(): 7 def __init__(self,ID,time): 8 self.next = None 9 self.prev = None 10 self.time = time 11 self.ID = ID 12 13 class solution(): 14 def __init__(self): 15 self.out_max_ID = None 16 self.out_max_time = 0 17 self.chain_head = None #储存双向链表头部 18 self.chain_rear = None #储存双向链表尾部 19 self.in_dict = {} 20 def IDin(self,ID,time): 21 #检查是否有头结点 22 if self.chain_head == None: 23 self.chain_head = chain(ID,time) 24 self.chain_rear = self.chain_head 25 self.in_dict[ID] = self.chain_head 26 else: 27 Node = chain(ID,time) 28 Node.prev = self.chain_rear 29 self.chain_rear.next = Node 30 self.chain_rear = Node 31 self.in_dict[ID] = Node 32 33 def IDout(self,ID,time): 34 #检查是否更新out_max_time以及out_max_ID 35 work_hour = time - self.in_dict[ID].time 36 if work_hour > self.out_max_time: 37 self.out_max_time = work_hour 38 self.out_max_ID = ID 39 40 #从字典与双向链表中删除 41 #如果链表仅剩一个节点 42 if self.chain_head.ID == self.chain_rear.ID: 43 self.chain_head = None 44 self.chain_rear = None 45 del self.in_dict[ID] 46 return None 47 48 #如果删除的节点是Head 49 if self.chain_head.ID == ID: 50 self.chain_head = self.chain_head.next 51 self.chain_head.prev = None 52 del self.in_dict[ID] 53 return None 54 55 #如果删除的节点是rear 56 if self.chain_rear.ID == ID: 57 self.chain_rear = self.chain_rear.prev 58 self.chain_rear.next = None 59 del self.in_dict[ID] 60 return None 61 62 self.in_dict[ID].prev.next = self.in_dict[ID].next 63 self.in_dict[ID].next.prev = self.in_dict[ID].prev 64 del self.in_dict[ID] 65 66 return None 67 68 def max_time(self,time): 69 if time - self.chain_head.time < self.out_max_time: 70 return self.out_max_time, self.out_max_ID 71 else: 72 return self.chain_head.time, self.chain_head.ID 73 74 if __name__ == "__main__": 75 text = solution() 76 text.IDin(1,1) 77 text.IDin(2,5) 78 text.IDin(3,10) 79 text.IDout(1,12) 80 text.IDout(2,15) 81 text.IDin(4,16) 82 time_result,id_result = text.max_time(16) 83 print(time_result,id_result)