一点摘抄,作为一点启发
海量数据 求最大的 K个数问题,如何解决?
-
按位划分区域,可以尽快的缩小范围,比如最高位 0 分一堆,1 分成一堆而且不用排序,这是第一选择。
-
最经典的方法当然是 堆 了,比如要求前1000个最大的数,那就直接建一个 1000 大小的小根堆,然后遍历,只要发现后面的数比小根堆的根节点大,就把根节点和该数交换,重新调整堆,遍历完之后,堆中的数自然就是最大的 1000 个数了;
-
当然能使用堆排序的前提是内存中要能够放得下这个 K,如果放不下呢?那就只能外部排序了,排序完之后拿到第 K 大的数即可,当然排序前可以和方法一搭配一下。
海量数据求中位数,如何解决?
-
可以按照位来分组,比如说最高位是0的一组,是 1 的一组,这样可以统计出那一组更少,这样就排除了一大半,然后继续这样排查,最终缩小范围后直接内部排序。
-
直接外部排序,然后取中间值,最笨的方法。
基数排序
基本思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较。
具体做法是:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
在海量数据中找出出现频率最高的前k个数
例如,在搜索引擎中,统计搜索最热门的10个查询词;在歌曲库中统计下载最高的前10首歌等。
-
如果重复率很高,可以采用前缀树,因为 trie 树适用于数据量大,重复多,但是数据种类小必须得可以放入内存;
-
按照 hash 进行分组,这样就能避免相同的数分到不同区域去了,导致不好统计。hash 分组完毕后,然后用前缀树 或者 hashmap 来计算每个组的前 k 个频率最高的数,最后对各个组的前 k 个数进行统计即可。
Trie 树
Trie又被称为前缀树、字典树
是一种树形结构,是一种哈希树的变种
优点:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
基本性质:
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同。
给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
这里我们把40亿个数中的每一个用32位的二进制来表示 假设这40亿个数开始放在一个文件中。
然后将这40亿个数分成两类: 1.最高位为0 2.最高位为1 并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20亿,而另一个>=20亿(这相当于折半了);与要查找的数的最高位比较并接着进入相应的文件再查找
再然后把这个文件为又分成两类: 1.次最高位为0 2.次最高位为1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10亿,而另一个>=10亿(这相当于折半了);与要查找的数的次最高位比较并接着进入相应的文件再查找。……. 以此类推,就可以找到了,而且时间复杂度为O(logn)。
参考链接:
https://mp.weixin.qq.com/s/Q6iKfWgOLUxgQ0pEL_9bnQ