伴学笔记:求两个集合并集大小的期望值
一、题目分析
小R有 n 个集合,每个集合中的元素都是唯一的且互不相同。小R希望通过随机选择两个集合,并计算它们的并集大小,来求出这个并集大小的期望值。要求最终结果保留两位小数。
输入格式
n:集合的数量。st:包含n个集合的列表,其中每个集合st[i]是一个整数列表,代表该集合中的元素。
输出格式
- 返回一个字符串,表示随机选择两个集合的并集大小的期望值,保留两位小数。
二、期望值计算
为了求出两个集合并集大小的期望值,可以从以下角度分析:
- 并集大小的期望:对于任意两个集合,求其并集大小相当于计算这两个集合中不同元素的数量。我们通过统计每个元素在多个集合中出现的频次,来计算它在并集中的概率。
- 元素出现次数的影响:如果一个元素在多个集合中出现,则它对并集大小的影响较小,反之,如果一个元素仅出现在少数几个集合中,则它对并集的贡献较大。
- 概率计算:对于每个元素,我们可以通过计算它出现在两个随机选择的集合中的概率,来估计它对并集大小的贡献。
三、解题思路
- 统计元素的出现次数:我们首先统计每个元素在所有集合中出现的次数。这可以通过一个字典
freq来完成,键为元素,值为元素在集合中出现的次数。 - 计算期望值:对于每个元素,计算它出现在两个集合中的概率,进而求出它对并集大小的贡献。最终将所有元素的贡献加起来,得到两个集合并集大小的期望值。
- 格式化输出:结果要求保留两位小数,因此需要在计算完期望值后格式化输出。
四、代码实现
from collections import defaultdict
def solution(n: int, st: list) -> str:
# 统计每个元素出现的集合数
freq = defaultdict(int)
for s in st:
for e in s:
freq[e] += 1
total_expected_union = 0.0 # 初始化期望并集大小
denominator = n * (n - 1) # 随机选两个集合的总可能数
# 遍历每个元素,计算其在并集中的概率
for k in freq.values():
# 计算每个元素出现在并集中的概率
probability = 1 - ((n - k) * (n - k - 1)) / denominator
total_expected_union += probability
# 格式化结果保留两位小数
return "{0:.2f}".format(total_expected_union)
# 测试用例
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')
五、代码解释
-
统计元素出现次数: 使用
defaultdict(int)来存储元素的出现频次。对于每个集合中的元素,我们将其在字典中对应的值加一,表示该元素在当前集合中出现。 -
计算期望值: 对于每个元素
k,它出现freq[k]次。我们需要计算这个元素出现在随机选择的两个集合中的概率。该概率为:P(element appears in the union)=1−(n−k)×(n−k−1)n×(n−1)P(\text{element appears in the union}) = 1 - \frac{(n - k) \times (n - k - 1)}{n \times (n - 1)}
其中,
n为集合的总数,k为当前元素的出现次数。分子部分计算了这个元素不出现在两个集合中的概率。 -
格式化输出: 通过
"{0:.2f}".format(total_expected_union)来确保结果保留两位小数。
六、复杂度分析
- 时间复杂度:O(n * m),其中
n为集合的个数,m为平均每个集合的元素个数。我们需要遍历每个集合中的每个元素来统计其出现频次。 - 空间复杂度:O(k),其中
k为元素的种类数。我们需要一个字典来存储每个元素的出现次数。
七、测试用例
-
输入:
solution(2, [[1, 2], [1, 3, 5]])输出:
'4.00' -
输入:
solution(3, [[1, 4], [2, 5], [3, 6, 7]])输出:
'4.67' -
输入:
solution(2, [[10, 20, 30], [10, 30, 50, 70]])输出:
'5.00'
八、总结
通过这个问题,我们学到了如何利用元素频率来计算期望值,尤其是在处理集合并集相关问题时,如何计算元素的贡献概率。希望大家能理解期望值的概念和概率计算方法,并能灵活运用于其他类似问题中。