并查集
主要用于解决元素分组的问题。主要操作有集合(或单个元素)的合并和查询元素所在的集合。
元素以在同一棵树下为标志,认为在同一集合中。多个集合对应着多棵不同的树,组成了森林。
逻辑上是树形结构,实际上用数组存储元素所在集合的根节点。
合并
合并 x 和 y 两个元素时,不能直接合并两个元素,而是要合并两个元素所在树的根节点。
查询
查询 x 和 y 是否在同一个集合,是查询 x 和 y 对应的根节点是否相同。
合并示例
代码
1 |
|
1 | 输入: |
主要用于解决元素分组的问题。主要操作有集合(或单个元素)的合并和查询元素所在的集合。
元素以在同一棵树下为标志,认为在同一集合中。多个集合对应着多棵不同的树,组成了森林。
逻辑上是树形结构,实际上用数组存储元素所在集合的根节点。
合并 x 和 y 两个元素时,不能直接合并两个元素,而是要合并两个元素所在树的根节点。
查询 x 和 y 是否在同一个集合,是查询 x 和 y 对应的根节点是否相同。
1 |
|
1 | 输入: |
1 |
|
有两个文件分别是a和b,各自存放了1亿条IP地址,限制内存100MB,找出两个文件中重复的ip地址。
总体思路是,把一个文件的内容输入到哈希表中,遍历另一个文件中的每一条IP地址,与哈希表中的key比对。因此只需要提供1个文件的内存占用即可。
IPv4地址的大小是4个字节。1亿是100M,则1亿条IP地址就是400MB。如果再加上unordered_map结构的地址域,那就要再翻倍,把一个文件输入到哈希表中就要占800MB内存。这显然是超出了100MB的要求。
可以这样:文件a的IP地址依次读取,取模(或者称之为哈希函数),比如%11
,这样把他们都分散到11个“桶”里。
把文件b也像这样,挨个IP地址取模,在a的相应的“桶”号下,去寻找。因为如果IP地址一样,用了相同的取模运算(哈希运算),所以是在同一个桶号里。
这样,就把1亿个IP地址分成了11波。内存压力减少到了80MB。
如果数据集中的最大值很大,那么中间有好多无效的空位被浪费。总体上还是浪费内存的。
结合了哈希+位数组的优势。内存使用效率高。