题目

不使用任何内建的哈希表库设计一个哈希集合

具体地说,你的设计应该包含以下的功能

  • add(value):向哈希集合中插入一个值。
  • contains(value) :返回哈希集合中是否存在这个值。
  • remove(value):将给定值从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。

示例:

MyHashSet hashSet = new MyHashSet();
hashSet.add(1);        
hashSet.add(2);        
hashSet.contains(1);    // 返回 true
hashSet.contains(3);    // 返回 false (未找到)
hashSet.add(2);          
hashSet.contains(2);    // 返回 true
hashSet.remove(2);          
hashSet.contains(2);    // 返回 false (已经被删除)

注意:

  • 所有的值都在 [1, 1000000]的范围内。
  • 操作的总数目在[1, 10000]范围内。
  • 不要使用内建的哈希集合库。

考点

1.哈希表O(1)。用数组空间换时间。data.resize(1000000,0);

2.二维数组,优化空间复杂度,1000个空数组 ,对数字取1000的余作为哈希值,定位到二维数组中,再除1000得到二度的哈希值。


思路

solution1

构造函数。顺序容器vector<int> data。重置数组大小:100w.

增:key对应的val设为1。

删:key对应的值设为0.

判断是否存在:bool返回 data[key]==1.

HashSet最有用的地方就是其能够在O(1)内判断某个元素是否存在,这都得归功于哈希表的作用。但是现在不让我们用了,但我们还是得保证其常数级的查找效率,那么就用空间来换时间吧。既然题目中说了数字的范围不会超过1000000,那么我们就申请这么大空间的数组,这样对于在HashSet中的数字,我们就将其标记为1,不在或者删除了的就标记为0,检测的时候就看其值是否为1即可.

solution2.

优化空间复杂度。二维数组,开始初始化1000个空数组,key%1000是哈希值(一维指针),key/1000是二维指针。

优化空间复杂度,由于存入HashSet的数字也许不会跨度很大,那么直接就申请长度为1000000的数组可能会有些浪费,那么我们其实可以使用1000个长度为1000的数组来代替,那么就要用个二维数组啦,实际上开始我们只申请了1000个空数组,对于每个要处理的元素,我们首先对1000取余,得到的值就当作哈希值,对应我们申请的那1000个空数组的位置,在加入元素时,一旦计算出了哈希值,我们将对应的空数组resize为长度1000,然后根据哈希值和key/1000来确定具体的加入位置。

移除数字一样的,先计算出哈希值,如果对应的数组不为空的话,找到对应的位置并赋值为0。

不过大家也可以看出来,我们在加入元素时会开辟1000的新空间,但是删除这个元素时,并没有检测这1000个位置是否均为0,是的话应该删除这1000个新空间。但是这样可能会使得删除函数变慢一些,


代码

solution1.

class MyHashSet {
public:
/** Initialize your data structure here. */
MyHashSet() {
data.resize(1000000, 0);
} void add(int key) {
data[key] = 1;
} void remove(int key) {
data[key] = 0;
} /** Returns true if this set contains the specified element */
bool contains(int key) {
return data[key] == 1;
} private:
vector<int> data;
};

solution2.

优化空间复杂度,由于存入HashSet的数字也许不会跨度很大,那么直接就申请长度为1000000的数组可能会有些浪费,那么我们其实可以使用1000个长度为1000的数组来代替,那么就要用个二维数组啦,实际上开始我们只申请了1000个空数组,对于每个要处理的元素,我们首先对1000取余,得到的值就当作哈希值,对应我们申请的那1000个空数组的位置,在加入元素时,一旦计算出了哈希值,我们将对应的空数组resize为长度1000,然后根据哈希值和key/1000来确定具体的加入位置。

移除数字一样的,先计算出哈希值,如果对应的数组不为空的话,找到对应的位置并赋值为0。

不过大家也可以看出来,我们在加入元素时会开辟1000的新空间,但是删除这个元素时,并没有检测这1000个位置是否均为0,是的话应该删除这1000个新空间。但是这样可能会使得删除函数变慢一些,

class MyHashSet {
public:
/** Initialize your data structure here. */
MyHashSet() {
data.resize(1000,vector<int>());
//二维数组初始化,第一个数是个数,第二个参数是元素类型,vector<int>()表示初始化为0的容器。要加()!!!!
} void add(int key) {
int hashkey=key%1000;
if(data[hashkey].empty())
{
data[hashkey].resize(1000,0);
}
data[hashkey][key/1000]=1;
//这个赋值操作写在if外部。只做一次哈希值判空!!
} void remove(int key) {
int hashkey=key%1000;
if(!data[hashkey].empty())
{
data[hashkey][key/1000]=0;
}
} /** Returns true if this set contains the specified element */
bool contains(int key) {
return !data[key%1000].empty()&& (data[key%1000][key/1000]==1);
} private: vector<vector<int>> data;
}; /**
* Your MyHashSet object will be instantiated and called as such:
* MyHashSet obj = new MyHashSet();
* obj.add(key);
* obj.remove(key);
* bool param_3 = obj.contains(key);
*/

问题

LeetCode705. Design HashSet的更多相关文章

  1. Leetcode705.Design HashSet设置哈希集合

    不使用任何内建的哈希表库设计一个哈希集合 具体地说,你的设计应该包含以下的功能 add(value):向哈希集合中插入一个值. contains(value) :返回哈希集合中是否存在这个值. rem ...

  2. 【Leetcode_easy】705. Design HashSet

    problem 705. Design HashSet 题意: solution1: class MyHashSet { public: /** Initialize your data struct ...

  3. [Swift]LeetCode705. 设计哈希集合 | Design HashSet

    Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...

  4. [LeetCode] Design HashSet 设计HashSet

    Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...

  5. LeetCode 705 Design HashSet 解题报告

    题目要求 Design a HashSet without using any built-in hash table libraries. To be specific, your design s ...

  6. [LeetCode&Python] Problem 705. Design HashSet

    Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...

  7. LeetCode 705:设计哈希集合 Design HashSet

    题目: 不使用任何内建的哈希表库设计一个哈希集合 具体地说,你的设计应该包含以下的功能 add(value):向哈希集合中插入一个值. contains(value) :返回哈希集合中是否存在这个值. ...

  8. Design HashSet

    Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...

  9. C#LeetCode刷题之#705-设计哈希集合​​​​​​​(Design HashSet)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4114 访问. 不使用任何内建的哈希表库设计一个哈希集合 具体地说 ...

随机推荐

  1. ruby逻辑判断符号

    puts true and false  #相当于 (puts true) and false Use &&/|| for boolean expressions, and/or fo ...

  2. ETL模型设计

    传统的关系数据库一般采用二维数表的形式来表示数据,一个维是行,另一个维是列,行和列的交叉处就是数据元素.关系数据的基础是关系数据库模型,通过标准的SQL语言来加以实现. 数据仓库是多维数据库,它扩展了 ...

  3. Nodejs计时器定时执行函数

    一.最low的定时器: 每次执行完间隔5s,然后继续执行 (function schedule() { setTimeout(do_it, 5000, schedule); }()); functio ...

  4. 封装WebService的APM为Async、Await模式利于Asp.Net页面调用

    Wcf针对Async.Await指令直接可以返回Task<T>结果,但是老旧的系统中还是会有很多是在用Soap的Webservice.直接在Asp.Net页面调用APM方法确实比较麻烦,其 ...

  5. 如何绘制ER图

    先画出多个实体(用长方形表示),然后是联系类型(菱形),和属性(椭圆).

  6. 安全漏洞 : XSS CSRF

    https://my.oschina.net/hc24/blog/527099 XSS成因概括 : XSS其实就是Html的注入问题,攻击者A的输入没有经过严格的控制进入了数据库,最终显示给来访的用户 ...

  7. 零基础逆向工程33_Win32_07_创建线程

    1 什么是线程(Threads)? 什么是多线程? 怎么在windows中观察多线程? 线程可以简单理解为主程序为解决一个问题而选择的其中一条路线. 同理,多线程就是同时选择不同的路线来解决此问题. ...

  8. jquery_lazyload插件

    延迟加载图片的 jQuery 插件 http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/

  9. vos设置禁止被叫特定号码段特定区域

    问题: 为了防止卡线遭投诉被运营商停,给公司带来损失,对一些特定号段特定区域要进行限制,不让客户呼出 打开VOS3000 落地网关——补充设置——落地被叫前缀——禁止 添加禁止号段 具体案例: 如填写 ...

  10. 源码安装zabbix3.2.7时PHP ldap Warning

    问题如下: 解决方法: 1.首先查看源码安装的php模块中是否有ldap.so [root@nms ldap]# ll  /usr/local/php/lib/php/extensions/no-de ...