海量数据判重

1. 问题描述

对于海量数据,要求判断一个数据是否已经存在。这个数据很有可能是字符串,例如 URL。

2. HashSet

最直观的方法是使用 HashSet 存储,那么就能以 O(1) 的时间复杂度判断一个数据是否已经存在。

考虑到数据是海量的,那么就需要使用拆分的方式将数据拆分到多台机器上,分别在每台机器上使用 HashSet 存储。我们需要使得相同的数据拆分到相同的机器上,可以使用哈希取模的拆分方式进行实现。

图片说明

3. BitSet

如果海量数据是整数,并且范围不大时,就可以使用 BitSet 存储。通过构建一定大小的比特数组,并且让每个整数都映射到这个比特数组上,就可以很容易地知道某个整数是否已经存在。因为比特数组比整型数组小的多,所以通常情况下单机就能处理海量数据。

图片说明

以下是一个 BitSet 的实现,当然在实际开发中可以直接使用语言内置的实现。

图片说明

使用 BitSet 还可以很容易地解决一个整数出现次数的问题,例如使用两个比特数组就可以存储 0~3 的信息。其实判重问题也可以简单看成一个数据出现的次数是否为 1,因此一个比特数组就够了。

4. 布隆过滤器

布隆过滤器能够以极小的空间开销解决海量数据判重问题,但是会有一定的误判概率。它主要用在网页黑名单系统、垃圾邮件过滤系统、爬虫的网址判重系统。

布隆过滤器也是使用 BitSet 存储数据,但是它进行了一定的改进,从而解除了 BitSet 要求数据的范围不大的限制。在存储时,它要求数据先经过 k 个哈希函得到 k 个位置,并将 BitSet 中对应位置设置为 1。在查找时,也需要先经过 k 个哈希函数得到 k 个位置,如果所有位置上都为 1,那么表示这个数据存在。

由于哈希函数的特点,两个不同的数通过哈希函数得到的值可能相同。如果两个数通过 k 个哈希函数得到的值都相同,那么使用布隆过滤器会将这两个数判为相同。

可以知道,令 k 和 m 都大一些会使得误判率降低,但是这会带来更高的时间和空间开销。

布隆过滤器会误判,也就是将一个不存在的数判断为已经存在,这会造成一定的问题。例如在垃圾邮件过滤系统中,会将一个邮件误判为垃圾邮件,那么就收不到这个邮件。可以使用白名单的方式进行补救。

图片说明

5. Trie

Trie 树又叫又叫字典树、前缀树、单词查找树,它是一颗多叉查找树。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。

如果海量数据是字符串数据,那么就可以用很小的空间开销构建一颗 Trie 树,空间开销和树高有关。

图片说明

Leetcode : Implement Trie (Prefix Tree)

图片说明

参考资料

个人博客

https://github.com/CyC2018/CS-Notes

开源在 Github 上的个人博客,总结了技术面试必备的基础知识,在 Github 上关注数排在二十名左右。

#leetcode##面经##笔试题目##春招##实习#
全部评论
优秀的cyc
点赞 回复 分享
发布于 2019-02-15 16:39
请问bitset的方法为什么要除32,模32,之前学过,后来忘了😂
点赞 回复 分享
发布于 2019-02-14 11:43
  前排围观巨佬
点赞 回复 分享
发布于 2019-02-14 10:34
膜巨佬
点赞 回复 分享
发布于 2019-02-13 23:46
配图颜值高
点赞 回复 分享
发布于 2019-02-13 23:42
谢谢,学习到了
点赞 回复 分享
发布于 2019-02-13 21:08
配图颜值高啊。
点赞 回复 分享
发布于 2019-02-13 20:32

相关推荐

哈哈哈,你是老六:百度去年裁员分评不好,赶紧弄点红包
点赞 评论 收藏
分享
一共一个小时,面试难度以及自己的回答算是最近的面试压力比较大的,实习问了30分钟,中间穿插八股。1.redis数据结构2.redis持久化机制3.mysql索引底层4.聚簇索引与非聚簇索引5.索引优化6.索引失效7.mysql执行一条sql8.那么多索引mysql怎么选(不会)9.tcp与udp区别10.tcp为什么可靠11.消息队列作用12.kafka怎么保证消息有序性13.mcp是什么?14.skills是什么?15.jvm内存分配与回收过程(我讲了从创建对象到判断垃圾对象到垃圾回收我全说了一遍,是这个吗?)16.fullgc触发机制17.tcp的拥塞控制流程(不会了)18.分布式事务解决方案,说了2pc,3pc,tcc。算法是反转双向链表,没有按格式输出,但是面试官没让继续写了,面完以为挂了,结果晚上秒过,看看复试什么情况吧。今天百度打电话准备发offer了,业务跟在手子的差不多,很垂,并且说不分日常暑期,只看表现,会有转正机会,但是考虑再三还是拒绝了,百度实习薪资确实有点低,title也不如之前了,但是面试的二位业务老师我很喜欢,对我的评价也不错,希望之后能有机会共事。从三月份到现在一共面了六家,面试次数总共是8场,情况如下:脉脉二面(无答复,默认挂)百度二面已oc美团一面过,下周一二面shein一面过直接HR面游族一面过直接HR面腾讯一面过等待约二面滴滴明天一面面试通过率还是蛮高的,但是大部分都是日常,感觉对我现在的加成不大,大概率不会去,不知道暑期会是什么情况呢唉,希望能有面试吧,继续加油。字节被无hc直接取消了,现在还没人捞,有没有字节HR救救我
不管什么都不想跳动了:本人美团百度快手都待过,建议肯定是直接留快手多一点产出后转正or直接冲字节腾讯暑期吧。一是快手从福利到基建都吊打另外两家。美团现在这个业务比较惨,本来毛利就很低,亏损严重,今年很可能要优化人力降低成本,去了别说日常,就算暑期后面都很可能被优化。百度其实实习生权限挺高的,可以接触到一些含金量高的项目,但是现在的风评不如之前了,薪资也不高。二是转正概率和薪资是跟产出挂钩的,你都在手子已经积累产出了,去其他家日常实习产出都是从0开始,肯定不可能有你在手子转正可能性大啊,现在日常压根没必要去,而且我有两个师弟都是在快手日常转正的,不用太担心,安心留在手子一边多做一点产出然后一边冲字节腾讯暑期,字节腾讯今年实习岗位非常多的,不如好好把握这个,加油。
查看18道真题和解析
点赞 评论 收藏
分享
评论
9
104
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务