问题描述
小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) :使用集合来存储每个集合的元素,这样可以方便地进行并集操作。集合的特性是元素唯一且无序,非常适合处理唯一元素的集合。
算法步骤
- 初始化总并集大小:我们需要一个变量来累加所有集合对的并集大小。
- 遍历所有可能的集合对:使用双重循环来遍历所有可能的集合对。由于集合对是无序的,我们只需要遍历
i < j的情况。 - 计算并集大小:对于每一对集合,计算它们的并集大小。
- 累加并集大小:将每一对集合的并集大小累加到总并集大小中。
- 计算期望值:将总并集大小除以集合对的总数,得到期望值。集合对的总数是
n * (n - 1) / 2。 - 格式化结果:将期望值格式化为两位小数。
详细步骤
-
初始化总并集大小:
- 使用一个变量
total_union_size来存储所有集合对的并集大小之和。
- 使用一个变量
-
遍历所有可能的集合对:
- 使用双重循环
for i in range(n)和for j in range(i + 1, n)来遍历所有可能的集合对。
- 使用双重循环
-
计算并集大小:
- 对于每一对集合
st[i]和st[j],使用set(st[i]) | set(st[j])计算它们的并集。 - 使用
len()函数获取并集的大小。
- 对于每一对集合
-
累加并集大小:
- 将每一对集合的并集大小累加到
total_union_size中。
- 将每一对集合的并集大小累加到
-
计算期望值:
- 将
total_union_size除以集合对的总数n * (n - 1) / 2,得到期望值。
- 将
-
格式化结果:
- 使用字符串格式化方法将期望值格式化为两位小数。
思考
计算两个集合的并集大小可以通过以下步骤实现:
- 将两个集合转换为集合类型:使用
set()函数将列表转换为集合。 - 计算并集:使用集合的并集操作符
|来计算两个集合的并集。 - 获取并集的大小:使用
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')