学习笔记:枚举与优化之unordered_set/map

Poki的学习笔记:枚举与优化之unordered_set/map


本笔记随时会更改,仅代表个人理解,参考了许多博文资料,也许会有很多错漏希望指正。

是什么

特点:无序

应用:快速查找删除 统计次数问题 无序容器

unordered_set&unordered_map内部实现均基于哈希表(采用除留余数法)
P.S. 哈希表——根据关键码值而进行直接访问的数据结构,通过相应的哈希函数(也称散列函数)处理关键字得到相应的关键码值,关键码值对应着一个特定位置,用该位置来存取相应的信息,这样就能以较快的速度获取关键字的信息。会存在不可避免的冲突问题。解决冲突的方法常见的有:开发地址法、再散列法、链地址法(也称拉链法)。而unordered_set/map内部解决冲突采用的是链地址法,当用冲突发生时把具有同一关键码的数据组成一个链表。[数据结构学了就不多赘述了>_<]

以unordered_set为例,在一个unordered_set内部,元素不会按任何顺序排序,而是通过元素值的hash值将元素分组放置到各个槽(Bucker,也可以译为“桶”),这样就能通过元素值快速访问各个对应的元素(均摊耗时为O(1))
当我只要访问而不需要顺序,想用空间弥补时间时,哈希表是很好的选择。

unordered_map与unordered_set区别

后者就是在哈希表插入value,而这个value就是它自己的key,而unordered_map有键-值对,unordered_set单纯就是为了方便查询这些值。

使用unordered_set的例子:给你A,B两组数,由整数组成,然后把B中在A中出现的数字取出来,要求用线性时间完成。很明显,这道题应该将A的数放到一个表格,然后线性扫描B,发现存在的就取出。可是A的范围太大,你不可能做一个包含所有整数的表,因为这个域太大了,所以我们就用unordered_set来存放A的数,具体实现库函数已经帮你搞定了。

与set/map的区别

*在使用上主要是有无序/稳定否的差别

有序/稳定/在意内存->set/map
无序/快速查找添加删除/不担心高内存->unordered_set/map

set/map内部由红黑树实现

以map&unordered_map为例:

map是STL的一个关联容器,它提供一对一(第一个为key,每个key只能在map中出现一次,第二个为value)的数据处理能力。map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),所以在map内部所有的数据都是有序的,且map的查询、插入、删除操作的时间复杂度都是O(logN)。在使用时,map的key需要定义operator<。

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的。unordered_map的key需要定义hash_value函数并且重载operator==。

两者均按键查找

运行效率方面:unordered_map最高,而map效率较低但提供了稳定效率和有序的序列。

占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

因而可以实现用空间换时间的优化操作。

但是并不是unordered_map查询时间一定比map短,因为实际情况中还要考虑到数据量,而且unordered_map的hash函数的构造速度也没那么快,所以不能一概而论,应该具体情况具体分析。哈希表的建立也比较耗费时间。

具体应用

例题:
在n个元素的数组中,找到差值为k的数字对去重后的个数
第一行:n——数字个数;k——差值
第二行:数字
Input:
5 2
1 5 3 4 2
Output:
3

#include <iostream>
#include <unordered_set>
using namespace std;
int n,k,x,ans=0;
unordered_set<int> myset;

int main()
{
   
    cin>>n>>k;
    for(int i=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值