小R的并集大小期望计算 | 豆包MarsCode AI刷题

52 阅读2分钟

要解决这个问题,需要计算 两个集合并集大小的期望值。这是一个数学和算法结合的问题,以下是具体的思路与实现步骤。


解题思路

1. 理解并集大小的计算

给定两个集合 AA 和 BB:

  • 并集大小公式为: ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣|A \cup B| = |A| + |B| - |A \cap B|

2. 随机选择两个集合

对于 nn 个集合,随机选择两个集合的组合有 (n2)=n(n−1)2\binom{n}{2} = \frac{n(n-1)}{2} 种。每种组合的并集大小需要计算一次。

3. 计算所有组合的并集大小

对于每对集合 (Ai,Aj)(A_i, A_j),计算其并集大小,并累计求和。

4. 计算期望

并集大小的期望公式为:

期望=所有并集大小的总和所有组合数\text{期望} = \frac{\text{所有并集大小的总和}}{\text{所有组合数}}

5. 结果保留两位小数

使用 Python 的 format 函数将结果格式化到两位小数。


算法实现

以下是基于上述思路的 Python 实现:

def union_expectation(n, sets):
    from itertools import combinations
    
    # 所有并集大小总和
    total_union_size = 0
    
    # 选择任意两个集合的组合
    pairs = list(combinations(range(n), 2))  # 生成所有集合下标对 (i, j)
    
    for i, j in pairs:
        set1, set2 = sets[i], sets[j]
        # 计算 |A ∪ B| = |A| + |B| - |A ∩ B|
        union_size = len(set1) + len(set2) - len(set1 & set2)
        total_union_size += union_size
    
    # 计算所有组合数
    total_combinations = len(pairs)
    
    # 计算期望值
    expectation = total_union_size / total_combinations
    
    # 返回保留两位小数的结果
    return f"{expectation:.2f}"

# 测试样例
print(union_expectation(2, [{1, 2}, {1, 3, 5}]))  # 输出: '4.00'
print(union_expectation(3, [{1, 4}, {2, 5}, {3, 6, 7}]))  # 输出: '4.67'
print(union_expectation(2, [{10, 20, 30}, {10, 30, 50, 70}]))  # 输出: '5.00'

代码解析

  1. 输入处理

    • 使用集合的交集 set1 & set2 和大小 len(set) 快速计算并集大小。
  2. 组合生成

    • 使用 itertools.combinations 生成所有集合下标的两两组合,避免手动嵌套循环。
  3. 期望计算

    • 累加所有并集大小,再除以组合总数,得到平均值。
  4. 结果格式化

    • 使用 f"{value:.2f}" 将结果保留两位小数。

测试与优化

时间复杂度

  • 组合生成:O(n2)O(n^2)
  • 并集计算:对于每对集合,集合操作时间复杂度与集合大小有关,设最大集合大小为 mm,复杂度为 O(m)O(m)。
  • 总复杂度:O(n2⋅m)O(n^2 \cdot m)

可扩展性

  • 如果集合数量 nn 或单个集合大小 mm 增大,可以通过优化集合操作或引入分布式计算处理超大规模数据。