211.小R的并集大小期望计算|豆包MarsCode AI刷题
问题描述
小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'
要点:
unordered_set:
- 定义:在C++中,
unordered_set是一个基于哈希表实现的集合容器,它属于STL(Standard Template Library,标准模板库)的一部分。unordered_set能够存储唯一元素,并且这些元素是无序的,即它们不以任何特定顺序存储。这意味着,当你向unordered_set中添加元素时,元素的存储位置是由其哈希值决定的,而不是按照插入顺序或元素值的大小顺序。 unordered_set的一些关键特性包括:
- 唯一性:不允许有重复的元素。如果尝试向
unordered_set中添加一个已经存在的元素,该操作将失败,并且集合的大小不会增加。 - 无序性:元素的存储顺序不是确定的,也不是有序的。这与
set容器不同,后者是基于红黑树实现的,并且元素始终按照严格的弱排序顺序存储。 - 哈希表基础:
unordered_set使用哈希表来存储元素,这使得查找、插入和删除操作在平均情况下具有常数时间复杂度(O(1))。然而,在最坏情况下(例如,所有的元素都哈希到同一个桶中),这些操作的时间复杂度可能会退化为线性时间复杂度(O(n))。 - 迭代器:
unordered_set提供迭代器来访问其元素。由于元素是无序的,所以这些迭代器不保证按照任何特定顺序遍历元素。 - 元素类型:
unordered_set中的元素必须是可哈希的,即它们必须有一个有效的哈希函数。默认情况下,C++标准库为大多数基本类型(如int、float、string等)提供了哈希函数。对于自定义类型,你需要提供一个哈希函数和一个相等比较函数。
ostringstream:
ostringstream 是 std 命名空间中的一个类,它属于输入输出流库(iostream library)。ostringstream 类提供了一个内存中的输出流,你可以像使用 std::cout 一样向它写入数据,但它不会将数据输出到控制台或文件,而是将数据存储在内部的字符串缓冲区中。
当你创建了一个 ostringstream 对象后,你可以使用各种插入操作符(如 <<)来向它发送数据。这些数据会被转换成字符串形式,并存储在 ostringstream 对象的内部缓冲区中。当你需要获取这个字符串时,可以调用 str() 成员函数,它会返回一个包含所有已写入数据的 std::string 对象。
代码分析
-
寻找并集
eg.样例2:
输入:
n = 3,st = [[1, 4], [2, 5], [3, 6, 7]]
输出:'4.67'定义string solution(int n, vector<vector> st)
为什么是二维? 我们将每一个集合看作一行。而
unordered_set可以保证每个元素只取一次,不重复,只要循环将其放入unordered_set。 -
求并集期望值
创建了一个
ostringstream对象oss。通过向oss发送流插入操作符<<,设置浮点数的输出格式为固定小数点表示法(fixed),并指定了小数点后保留的位数为2(setprecision(2))。然后,将averageUnionSize的值发送到oss,这样它就会被格式化为一个保留两位小数的字符串。调用oss.str()方法获取了oss中存储的字符串,并将其作为函数的返回值。
#include <iostream>
#include <vector>
#include <unordered_set>
#include <iomanip>
#include <numeric> // For std::accumulate
using namespace std;
string solution(int n, vector<vector<int>> st) {
double totalUnionSize = 0.0;
int pairCount = 0;
// Iterate through all pairs of sets
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
unordered_set<int> unionSet(st[i].begin(), st[i].end());
// 将 st[j] 中的所有元素添加到 unionSet 中
// 这一步会自动处理重复元素,因为 unordered_set 不允许重复
unionSet.insert(st[j].begin(), st[j].end());
totalUnionSize += unionSet.size();
++pairCount;
}
}
// Calculate the average union size
double averageUnionSize = totalUnionSize / pairCount;
// Format the result to two decimal places
ostringstream oss;
oss << fixed << setprecision(2) << averageUnionSize;
return oss.str();
}
int main() {
cout << solution(2, {{1, 2}, {1, 3, 5}}) << endl; // Output: 4.00
cout << solution(3, {{1, 4}, {2, 5}, {3, 6, 7}}) << endl; // Output: 4.67
cout << solution(2, {{10, 20, 30}, {10, 30, 50, 70}}) << endl; // Output: 5.00
return 0;
}