线上实验问题分类解析

107 阅读4分钟

题目解析:线上实验问题分类

问题描述

小M收到了一条报警日志,统计了多个用户对实验的命中情况,并通过查询尝试对问题进行分类。每次查询会提供一组条件,条件可以是:

  1. 必须命中某些实验;
  2. 必须未命中某些实验。

对于每个查询,需要统计满足条件的用户数量。


思路分析

  1. 数据结构选择

    • 每个用户的实验命中情况用集合 set 表示,方便快速查询实验是否命中。
    • 查询条件通过解析 正负值 来分别表示 "命中" 和 "未命中" 的要求。
  2. 查询实现

    • 对于每个查询,依次检查每个用户的命中情况。

    • 对每个条件:

      • 如果条件为正值(例如 1),检查该用户是否命中实验 1
      • 如果条件为负值(例如 -2),检查该用户是否未命中实验 2
    • 如果用户满足所有条件,计数加一。

  3. 复杂度分析

    • 假设用户数量为 NN,每个用户的实验命中列表长度为 kk,查询次数为 QQ,每个查询条件长度为 cc。

      • 转换用户实验数据到集合的复杂度:O(N⋅k)O(N \cdot k)。
      • 对每个查询检查所有用户的复杂度:O(Q⋅N⋅c)O(Q \cdot N \cdot c)。
    • 因此,总时间复杂度约为 O(N⋅k+Q⋅N⋅c)O(N \cdot k + Q \cdot N \cdot c),其中 kk 和 cc 通常较小。


代码实现

以下是具体代码实现:

def solution(n, m, q, arrayN, arrayQ):
    # 将用户的实验命中情况转换为集合,方便后续查询判断
    user_hits = [set(experiments[1:]) for experiments in arrayN]
    
    results = []
    
    # 对每个查询进行处理
    for query in arrayQ:
        count = 0
        # 获取查询的条件
        conditions = query[1:]
        
        # 检查每个用户是否满足查询条件
        for hits in user_hits:
            satisfied = True
            for condition in conditions:
                exp_id = abs(condition)
                if condition > 0:  # 要求命中此实验
                    if exp_id not in hits:
                        satisfied = False
                        break
                else:  # 要求未命中此实验
                    if exp_id in hits:
                        satisfied = False
                        break
            if satisfied:
                count += 1
        
        # 记录符合当前查询条件的用户数量
        results.append(count)
    
    return results


# 测试用例
print(
    solution(
        3,
        3,
        3,
        [[2, 1, 2], [2, 2, 3], [2, 1, 3]],
        [[2, 1, -2], [2, 2, -3], [2, 3, -1]]
    )
)  # 预期输出 [1, 1, 1]

测试用例详解

示例输入:

n = 3  # 用户数量
m = 3  # 实验数量
q = 3  # 查询次数

# 用户的实验命中列表
arrayN = [
    [2, 1, 2],  # 用户 1 命中实验 1 和 2
    [2, 2, 3],  # 用户 2 命中实验 2 和 3
    [2, 1, 3]   # 用户 3 命中实验 1 和 3
]

# 查询条件
arrayQ = [
    [2, 1, -2],  # 条件:命中实验 1,未命中实验 2
    [2, 2, -3],  # 条件:命中实验 2,未命中实验 3
    [2, 3, -1]   # 条件:命中实验 3,未命中实验 1
]

示例输出:

  • 查询 1:[命中实验 1,未命中实验 2]

    • 用户 1:命中 1,未命中 2(不满足条件)。
    • 用户 2:命中 2,未命中 1(不满足条件)。
    • 用户 3:命中 1,未命中 2(满足条件)。
      结果:1
  • 查询 2:[命中实验 2,未命中实验 3]

    • 用户 1:命中 2,未命中 3(满足条件)。
    • 用户 2:命中 2,未命中 3(不满足条件)。
    • 用户 3:命中 3,未命中 2(不满足条件)。
      结果:1
  • 查询 3:[命中实验 3,未命中实验 1]

    • 用户 1:命中 1,未命中 3(不满足条件)。
    • 用户 2:命中 3,未命中 1(满足条件)。
    • 用户 3:命中 3,未命中 1(不满足条件)。
      结果:1

最终输出结果为:

[1, 1, 1]

图解分析

数据结构转换:

用户实验数据从列表转换为集合,便于快速查找:

  • 用户 1:{1, 2}
  • 用户 2:{2, 3}
  • 用户 3:{1, 3}

查询条件解析:

每个查询中的条件通过正负值解析为 "命中/未命中" 判断规则。例如:

  • 查询 [2, 1, -2] 转换为:命中实验 1,未命中实验 2

条件判断流程:

对每个查询,依次检查用户的实验命中情况,通过逻辑判断是否满足条件。


总结

本题的难点在于:

  1. 合理使用数据结构(集合)简化条件判断。
  2. 高效处理用户与查询的多对多匹配关系。

通过 Marscode AI 的在线调试功能,可以快速验证逻辑、调试边界情况,并改进代码实现。此外,AI 提供的逐步提示与测试用例覆盖功能,使得问题的分析与解决更加高效。