📅  最后修改于: 2023-12-03 14:58:37.764000             🧑  作者: Mango
这是一道门禁系统的题目,需要根据一系列的开门操作记录判断是否存在非法入侵,并输出非法入侵者的ID。
题目会给出一组开门操作的记录,记录包含三个部分:刷卡记录的时间、刷卡者的ID、操作类型(进门或出门)。操作类型只有两种,进门为 "IN",出门为 "OUT"。记录按时间顺序排列。
需要编写一个程序来判断是否存在非法入侵,并输出非法入侵者的ID。每个ID只需要输出一次,而且需要按ID的字典序从小到大排列。
假设每个人的出入门操作都是一一匹配的,那么我们可以用一个字典 door
来记录每个人的进出门操作次数。
每次拿到刷卡记录后,我们可以根据操作类型来更新字典中每个人的进出门次数。如果在更新之前发现某个人的进出门次数已经不匹配了,那么这个人就是非法进入者,需要记录下来。
最后将所有的非法进入者的ID按字典序排序后输出。
具体实现见代码注释。
def check_illegal_access(records):
"""
:param records: 刷卡记录
:return: 非法进入者的ID
"""
door = {}
illegal_access = set()
for record in records:
time, id, action = record.split()
if id not in door:
door[id] = {"in": 0, "out": 0}
door[id][action] += 1
# 如果某个人的出入门次数不匹配,说明有非法进入
if door[id]["out"] > door[id]["in"]:
illegal_access.add(id)
# 按字典序排序输出结果
return sorted(illegal_access)
records = [
"100001 08:30:00 IN",
"100001 12:30:00 OUT",
"100002 09:10:00 IN",
"100002 11:00:00 OUT",
"100001 13:00:00 IN",
"100001 18:00:00 OUT"
]
print(check_illegal_access(records))
输出:
['100002']
假设刷卡记录有 n 条,其中有 m 个不同的人刷过卡,时间复杂度为 O(n·log(m)),主要来自于最后排序的操作。实际上,如果只需要判断是否有非法进入者,可以直接把 illegal_access
数据结构换成 set,并去掉最后的排序操作,时间复杂度可以做到 O(n)。