Leetcode刷题记录 2023/10/12

2562. 找出数组的串联值

递归地把整数数组的头尾相接,两数拼接为一个数字,求所有拼接数字的和。

题目链接
简单题,考察一个string与int之间的相互转换。
int到string使用std::to_string(),string到int使用std::atoi()即可。
代码略。

705&706. 设计hash集合/hash映射

不使用编程语言底层实现的hash库,自己实现可以添加/查找/删除/构造函数初始化的hash集合与hash映射(映射即(key,value)二元组)。

题目链接1 & 题目链接2
同样是简单题,主要关注hash表的两种策略,以及代码实现中一些C++的现代特性。

为了实现哈希集合这一数据结构,有以下几个关键问题需要解决:

  • 哈希函数:能够将集合中任意可能的元素映射到一个固定范围的整数值,并将该元素存储到整数值对应的地址上。
  • 冲突处理:由于不同元素可能映射到相同的整数值,因此需要在整数值出现「冲突」时,需要进行冲突处理。总的来说,有以下几种策略解决冲突:
    • 链地址法:为每个哈希值维护一个链表,并将具有相同哈希值的元素都放入这一链表当中。
    • 开放地址法:当发现哈希值 h h h处产生冲突时,根据某种策略,从 h h h出发找到下一个不冲突的位置。
    • 再哈希法:当发现哈希冲突后,使用另一个哈希函数产生一个新的地址。
  • 扩容:当哈希表元素过多时,冲突的概率将越来越大,而在哈希表中查询一个元素的效率也会越来越低。因此,需要开辟一块更大的空间,来缓解哈希表中发生的冲突。

哈希函数选用最简单的,直接对质数取模。(hash模数的因子越少,空间越多,则hash效果越好)。
冲突处理使用链地址法,为每个hash值维护一个链表。
容器选择使用vector,比较好写。
细节先看代码。

class HashSet{
	vector<list<int>> data;//每个位置对应一个链表list
	//hashlist换成 vector<list<pair<int,int>>> data 即可。
	static int base = 857;//随意质数即可
	inline int hash(int n) {return n%base;} 
public:
	HashList():data(base){};
	void add(int key){
		int h = hash(key);//取得hash值
		//最标准的写法
		for(auto it = data[h].begin(); it != data[h].end(); ++it){
			if ((*it) == key) {
                return;
            }
            //hashlist
            if(it->first == key) it->second = value;
		}
		data[h].emplace_back(data);//*1
	}
	void remove(int key){
		int h = hash(key);
		for(auto it = data[h].begin(); it != data[h].end(); ++it){
			if ((*it) == key) {
                data[h].erase(it);
                return;
            }
		}
	}
	int find(int key){
		int h = hash(key);
		for(auto it = data[h].begin(); it != data[h].end(); ++it){
			if ((*it) == key) {
                return 1;
            }
            //hashlist:
            if(it->first == key) return it->second;
		}
		return -1;
	}
}

注意题中的emplace_back。
emplace_back是 C++11 的一个新特性。emplace_back() 和 push_back() 的区别是:push_back() 在向 vector 尾部添加一个元素时,首先会创建一个临时对象,然后再将这个临时对象移动或拷贝到 vector 中(如果是拷贝的话,事后会自动销毁先前创建的这个临时元素);而 emplace_back() 在实现时,则是直接在 vector 尾部创建这个元素,省去了移动或者拷贝元素的过程。
原文链接
另外,枚举关键字时使用auto比使用类型指明更加方便;枚举时懂得使用range from(:)也能节省大量的时间【例如:for(auto&& p:data[h])】。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值