这周的algo讲的hashing的基本概念,以及universal hashing和bloom filters。
universal hashing基本是说一种hash functions的构建方法,使得对不同输入的两次hash出现碰撞的概率不大于1/n(n是bucket的数量)。这东西是对应余数hash或者乘法hash之类的,说实话具体细节我是没怎么听懂,就有个大致概念。。。
bloom filters听起来比较酷炫,它做的事情看起来和hash table没啥区别,都是快速查找一个数据是否属于特定集合,但是它的优点是它需要的空间复杂度极小,代价是可能会有false positive。也就是说你想查找集合里有没有数据a,明明是没有的,它查了之后却告诉你有。不过漏报率足够低的话,外加上特定应用场景,这点误差其实可以是无所吊谓的。比如说你设置某网站的账户密码,网站看了你的密码告诉你这个密码太简单,要重输,这里就可以用bloom filters,哪怕你输了个足够复杂的密码却被网站告诉不行,那其实也没什么关系,大不了重输一个罢了。
bloom filters的做法是,设置一个固定位数的数组作为bucket,数组只存储0和1两种数据,弄一些hash functions,对于每个输入,每个hash function都把某一位变成1。查找的时候同样是每个hash function都对输入求一遍,看输出位是不是1,如果有输出位有0,那么就是不属于目标集合了。
这种方法适合查找,也可以对目标集合做添加操作,但是删除就不太方便了。而且为什么会漏报也是显然的,很明显如果你的bucket搞到后面全都是1了,那随便来个什么输入都有可能会让它通过的。这里有个两难问题就是hash function的数量和数组的位数的比例究竟该怎么设,如果这个比例太小的话,比如就只有一个hash function,那么一开始的漏报基准就很高。如果比例很大,比如很多个hash function,那么一开始会运行良好,但是到后面漏报率会急速提升。所以这也是个典型的trade off的问题。
最后,这周的assignment也很囧,实际上就是LeetCode里面那道two sum的题,不过assignment这道题如果还是用hash table求的话,时间复杂度很高的,基本要运行一两个小时的样子。所以最后用的二叉树搜索求的,一两秒就解决了。话说这个应该算偷懒吧,我连二叉搜索树都不是自己写的,直接import bisect。。。