最近我在空闲时间学习不同的算法,其中一个我发现非常有趣的算法是称为HyperLogLog算法,它可以估算列表中有多少个唯一项。
这对我来说特别有趣,因为它让我想起了我使用MySQL时看到的“Cardinality”值(直到最近我总是认为它是计算而非估算)。
因此,我知道如何编写时间复杂度为O(n)的算法来计算数组中有多少个唯一项。我用JavaScript写了这个算法:
function countUniqueAlgo1(arr) {
var Table = {};
var numUnique = 0;
var numDataPoints = arr.length;
for (var j = 0; j < numDataPoints; j++) {
var val = arr[j];
if (Table[val] != null) {
continue;
}
Table[val] = 1;
numUnique++;
}
return numUnique;
}
但问题在于,尽管我的算法具有O(n)的时间复杂度,但使用了大量的内存(将值存储在Table中)。我一直在阅读这篇关于如何在O(n)的时间内且使用最小内存计数列表中重复项的论文。
它解释说,通过哈希和计数位或其他方法,可以估计一个列表中独特项的数量。假设该列表均匀分布,则可以在一定概率内实现估计。
我已经阅读了这篇论文,但似乎无法理解它。能否有人给出更通俗易懂的解释?我知道哈希是什么,但我不明白它们如何在这个HyperLogLog算法中使用。