问题描述
AB 实验作为推荐策略迭代的有力工具,经常会有新的实验上线,以及一些无效策略的下线。在这些迭代过程中,难免会遇到意料之外的情况,导致部分服务崩溃而不可用。为了避免系统的全面崩溃,工程师们会添加监控报警,确保第一时间通知到值班同学进行处理。
小M同学刚刚开始负责线上报警的值班工作。很快,她就收到了第一条报警日志。在报警的时间范围内,小M同学收到了 NN 名用户的反馈,每位用户编号为 11 到 NN。小M同学查询线上实验后,统计了用户命中实验的列表,其中第 ii 位用户命中了 kiki 个实验,第 jj 个实验的编号为 ai,jai,j。
这些用户的反馈并不完全是由于一个问题造成的,因此小M同学需要对这些问题进行分类。根据先前的经验,小M同学会进行 QQ 次询问尝试对问题进行分类,第 ii 次询问会给出一个序列 bi,1,bi,2,…,bi,cibi,1,bi,2,…,bi,ci,cici 表示第 ii 次查询的实验数量。当 bi,j>0bi,j>0 时表示命中实验 ∣bi,j∣∣bi,j∣,否则表示未命中实验 ∣bi,j∣∣bi,j∣。小M同学需要得到符合这些条件的用户数。例如,序列 1, -2, 3 表示命中实验 1, 3 且未命中实验 2 的用户数量。
小M同学初来乍到,希望你能帮她解决这个问题。
测试样例
样例1:
输入:
n = 3, m = 3, q = 3, arrayN = [[2, 1, 2], [2, 2, 3], [2, 1, 3]], arrayQ = [[2, 1, -2], [2, 2, -3], [2, 3, -1]]
输出:[1, 1, 1]
样例2:
输入:
n = 5, m = 4, q = 2, arrayN = [[3, 1, 2, 3], [1, 2], [2, 1, 4], [3, 2, 3, 4], [2, 1, 3]], arrayQ = [[3, 1, -4, 2], [2, -1, -3]]
输出:[1, 1]
样例3:
输入:
n = 4, m = 3, q = 2, arrayN = [[1, 1], [2, 2, 3], [1, 3], [2, 1, 2]], arrayQ = [[1, -3], [2, 2, 3]]
输出:[2, 1]
解决思路
这道题可以拆解为以下几个步骤:
-
解析输入数据:
n是用户的数量,m是实验的数量,q是查询的次数。arrayN是每个用户命中的实验列表。arrayQ是查询条件列表,查询条件可以是正数(命中实验)或负数(未命中实验)。
-
数据表示和查询条件匹配:
- 用一个字典表示每个用户命中的实验,用集合存储实验编号便于快速查找。
- 遍历每个查询条件,统计满足该条件的用户数量。
-
匹配逻辑:
-
对于每个查询条件(例如
[2, 1, -2]),分别检查每个用户是否符合:- 如果条件是正数,例如
1,则用户必须命中实验1。 - 如果条件是负数,例如
-2,则用户不能命中实验2。
- 如果条件是正数,例如
-
若所有条件均满足,则统计该用户。
-
-
输出结果:
- 每个查询条件的匹配结果存储为一个数组,最终返回结果。
def solution(n, m, q, arrayN, arrayQ):
# 将每个用户的命中实验列表转化为集合
user_experiments = [set(user[1:]) for user in arrayN]
# 存储结果
result = []
# 遍历每个查询条件
for query in arrayQ:
count = 0 # 记录符合条件的用户数量
conditions = query[1:]
# 遍历每个用户
for user in user_experiments:
match = True
for cond in conditions:
experiment = abs(cond)
if cond > 0 and experiment not in user: # 必须命中
match = False
break
if cond < 0 and experiment in user: # 必须未命中
match = False
break
if match:
count += 1
result.append(count)
return result