求最长工作时间的算法面试题python

前几天面试算法岗遇到这样一道题目:给定一个实时的数据流,分别是员工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)
博主原创内容,禁止一切形式转载
原文地址:https://www.cnblogs.com/statruidong/p/10453228.html