赞
踩
1.IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;
2.可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,
把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
3.对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,
同时记录当前出现次数最多的那个IP地址;
4.可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的 IP;
1、先对这批海量数据预处理,在O(N)的时间内用Hash表完成统计
2、借助堆这个数据结构,找出Top K,时间复杂度为 N‘logK。即,借助堆结构,我们可以在log量级的时间内查找和调整/移动。
方案 2:
如果允许有一定的错误率,可以使用 Bloom filter,4G内存大概可以表示340亿bit。
将其中一个文件中的url使用Bloom filter 映射为这340亿 bit,然后挨个读取另外一个文件的url,方案 2:
也可采用与第1题类似的方法,进行划分小文件的方法。
然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。方案 1:
读入要查询的数,查看相应bit位是否为 1,为1表示存在,为0表示不存在。申请512M的内存,一个bit位代表一个unsigned int 值。读入40亿个数,设置相应的bit位,
方案 2:
又因为2^32为40亿多,所以给定一个数可能在,也可能不在其中;这个问题在《编程珠玑》里有很好的描述,大家可以参考下面的思路,探讨一下:
方案1:
这题是考虑时间效率。用trie树统计每个词出现的次数,时间复杂度是 O(n*le)(le 表示单词的平准长度)。
然后是找出出现最频繁的前10个词,可以用堆来实现,前面的题中已经讲到了,
方案 1:这题用 trie 树比较合适,hash_map 也应该能行。
首先根据用 hash 并求模,将文件分解为多个小文件,对于单个文件利用上题
的方法求出每个文件件中 10 个最常出现的词。然后再进行归并处理,找出最终的 10 个最
常出现的词。
并把x利用插入排序的思想,插入到序列L中。依次循环,知道扫描了所有的元素。复杂度为 O(100w*100)。
方案 1:
采用 trie 树,关键字域存该查询串出现的次数,没有出现为 0。
最后用 10 个元素的最小推来对出现频率进行排序。
关于此问题的详细解答,请参考Top K 算法问题的实现。
先大体估计一下这些数的范围,比如这里假设这些数都是 32 位无符号整数(共有 2^32 个)。
我们把 0 到 2^32-1 的整数划分为 N 个范围段,每个段包含(2^32)/N 个整数。
比如,第一个段位 0 到 2^32/N -1,第二段为(2^32 )/N 到(2^32)/N -1,…,
第 N 个段为(2^32)( N -1)/N 到 2^32-1。
然后,扫描每个机器上的 N 个数,把属于第一个区段的数放到第一个机器上,
属于第二个区段的数放到第二个机器上,…,属于第 N 个区段的数放到第 N 个机器上。
注意这个过程每个机器上存储的数应该是 O(N)的。
下面我们依次统计每个机器上数的个数,一次累加,直到找到第 k 个机器,
在该机器上累加的数大于或等于(N^2 )/2,而在第 k-1 个机器上的累加数小于(N^2 )/2,并把这个数记为 x 。
那么我们要找的中位数在第 k 个机器中,排在第(N^2)/2-x 位。然后我们对第 k 个机器的数排序,
并找出第(N^2)/2-x 个数,即为所求的中位数的复杂度是 O(N^2)的。
方案 2:
先对每台机器上的数进行排序。排好序后,我们采用归并排序的思想,
将这 N个机器上的数归并起来得到最终的排序。
找到第(N^2 )/2 个便是所求。复杂度是 O(N^2*lgN^2)的。
要求线性的时间算法。
方案 1:
最先想到的方法就是先对这 n 个数据进行排序, 然后一遍扫描即可确定相邻的最大间隙。
但该方法不能满足线性时间的要求。
故采取如下方法:
1. 找到 n 个数据中最大和最小数据 max 和 min。
2. 用 n- 2 个点等分区间[min, max],即将[min, max]等分为 n-1 个区间(前闭后开区间),
将这些区间看作桶,编号为 1,2,…,n-2,n-1,且桶 i 的上界和桶 i+1 的下届相同,
即每个桶的大小相同。每个桶的大小为:
实际上,这些桶的边界构成了一个等差数列(首项为 min,公差为 d=dblAvrGap),
且认为将 min放入第一个桶,将 max 放入第 n-1 个桶。
3. 将 n 个数放入 n-1 个桶中:将每个元素 x[i] 分配到某个桶(编号为 index ),其中
,并求出分到每个桶的最大最小数据。
由抽屉 原理可知至少有一个桶是空的,又因为每个桶的大小相同,所以最大间隙不会在同4. 最大间隙:除最大最小数据 max 和 min 以外的 n-2 个数据放入 n- 1 个桶中,
一桶中出现,一定是某个桶的上界和气候某个桶的下界之间隙,且该量筒之间的桶
(即便好在该连个便好之间的桶)一定是空桶。也就是说,
最大间隙在桶 i 的上界和桶 j 的下界之间产生 j>=i+1。一遍扫描即可完成。
要求将其中交集不为空的集合合并,要求合并完成的集合之间无交集,例如上例应输出
{aaa, bbb,ccc,ddd, hhh}, {eee,ffff }, { ggg }
(1) 请描述你解决这个问题的思路;
(2) 给出主要的处理流程,算法,以及算法的复杂度;
(3) 请描述可能的改进。
方案 1:
采用并查集。首先所有的字符串都在单独的并查集中。然后依扫描每个集合,
顺序合并将两个相邻元素合并。例如,对于{aaa,bbb,ccc},首先查看 aaa 和 bbb 是否在同一个并查集中,
如果不在,那么把它们所在的并查集合并,然后再看 bbb 和 ccc 是否在同一个并查集中,
如果不在,那么也把它们所在的并查集合并。接下来再扫描其他的集合,
当所有的集合都扫描完了,并查集代表的集合便是所求。
复杂度应该是 O(NlgN)的。
改进的话,首先可以记录每个节点的根结点,改进查询。合并的时候,可以把大的和小的进行合,
这样也减少复杂度。
这个问题可以动态规划的思想解决。设 b[i]表示以第 i 个元素 a[i]结尾的最大子
序列,那么显然 b[i+1]=b[i]>0?b[i]+a[i+1]:a[i+1]。基于这一点可以很快用代码实现。
最大子矩阵问题:
给定一个矩阵(二维数组),其中数据有大有小,请找一个子矩阵,使得子矩阵的和最大,并输出这个和。
方案 2:
那么在这个范围内,其实就是一个最大子序列问题。如何确定第 i 列和第 j可以采用与最大子序列类似的思想来解决。如果我们确定了选择第 i 列和第 j列之间的元素,
列可以词用暴搜的方法进行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。