AI 刷题 211. 小R的并集大小计算 | 豆包MarsCode AI刷题

55 阅读3分钟

问题描述

小R有 n 个集合,她想通过随机选择两个集合,并计算它们的并集,来求出这个并集大小的期望值。每个集合中的元素都是唯一的且互不相同。她需要计算出随机选择两个集合并集大小的期望值,并且要求结果保留两位小数。

保证输入至少有两个集合。


测试样例

样例1:

输入:n = 2,st = [[1, 2], [1, 3, 5]]
输出:'4.00'

样例2:

输入:n = 3,st = [[1, 4], [2, 5], [3, 6, 7]]
输出:'4.67'

样例3:

输入:n = 2,st = [[10, 20, 30], [10, 30, 50, 70]]
输出:'5.00'

解析

问题理解

我们需要计算随机选择两个集合的并集大小的期望值。每个集合中的元素都是唯一的且互不相同。

数据结构选择

  • 集合(Set) :使用集合来存储每个集合的元素,这样可以方便地进行并集操作。集合的特性是元素唯一且无序,非常适合处理唯一元素的集合。

算法步骤

  1. 初始化总并集大小:我们需要一个变量来累加所有集合对的并集大小。
  2. 遍历所有可能的集合对:使用双重循环来遍历所有可能的集合对。由于集合对是无序的,我们只需要遍历 i < j 的情况。
  3. 计算并集大小:对于每一对集合,计算它们的并集大小。
  4. 累加并集大小:将每一对集合的并集大小累加到总并集大小中。
  5. 计算期望值:将总并集大小除以集合对的总数,得到期望值。集合对的总数是 n * (n - 1) / 2
  6. 格式化结果:将期望值格式化为两位小数。

详细步骤

  1. 初始化总并集大小

    • 使用一个变量 total_union_size 来存储所有集合对的并集大小之和。
  2. 遍历所有可能的集合对

    • 使用双重循环 for i in range(n)for j in range(i + 1, n) 来遍历所有可能的集合对。
  3. 计算并集大小

    • 对于每一对集合 st[i]st[j],使用 set(st[i]) | set(st[j]) 计算它们的并集。
    • 使用 len() 函数获取并集的大小。
  4. 累加并集大小

    • 将每一对集合的并集大小累加到 total_union_size 中。
  5. 计算期望值

    • total_union_size 除以集合对的总数 n * (n - 1) / 2,得到期望值。
  6. 格式化结果

    • 使用字符串格式化方法将期望值格式化为两位小数。

思考

计算两个集合的并集大小可以通过以下步骤实现:

  1. 将两个集合转换为集合类型:使用 set() 函数将列表转换为集合。
  2. 计算并集:使用集合的并集操作符 | 来计算两个集合的并集。
  3. 获取并集的大小:使用 len() 函数获取并集的大小。

代码实现

def solution(n: int, st: list) -> str:
    # 初始化总并集大小
    total_union_size = 0
    
    # 遍历所有可能的集合对
    for i in range(n):
        for j in range(i + 1, n):
            # 计算集合 st[i] 和 st[j] 的并集大小
            union_size = len(set(st[i]) | set(st[j]))
            # 累加并集大小
            total_union_size += union_size
    
    # 计算期望值
    expected_value = total_union_size / (n * (n - 1) / 2)
    
    # 将结果格式化为两位小数
    return f"{expected_value:.2f}"

if __name__ == '__main__':
    print(solution(2, [[1, 2], [1, 3, 5]]) == '4.00')
    print(solution(3, [[1, 4], [2, 5], [3, 6, 7]]) == '4.67')
    print(solution(2, [[10, 20, 30], [10, 30, 50, 70]]) == '5.00')