查找出现超过n / k次的所有元素

时间:2014-09-19 02:04:56

标签: algorithm

给定大小为n且数字为k的数组,查找出现超过n / k次的所有元素。

我相信这个问题可以通过摩尔投票算法的技术来解决,通过创建一个大小为k的地图来存储数字及其频率。

步骤:

首先创建大小为k的映射并从数组中插入前k个元素并更新其相应的频率。

对于下一个k元素,如果地图中存在数字,则增加其计数,否则减少具有最低计数值的现有数字的计数(我们可以通过保持另一个地图在恒定时间内找到它)如果计数永远下降到0删除来自地图的数量并添加新号码。

最后检查地图中是否存在数字的频率是否大于n / k。

我期待您的反例或评论。

例如:考虑n = 10且k = 2

考虑场景

2,2,2,7,1,3,5,6,8,9

地图的大小为2。

对于第一个元素,它只包含2个计数3。 为7它将插入(因为地图有空闲块)并更新它计数1。 对于1它不在地图中找到最低计数候选者在这种情况下它是7减少它的计数现在7的计数是0所以通过插入1和设置计数1来更新条目。 这个过程将一直持续到阵列末尾,我们在地图2和9中留下了两个候选者,他们的计数是3和1。

我们将检查有计数的元素和返回结果的计数> N / K。 (我们不需要循环遍历数组k次,我们可以将计数最初存储在其他地图中)所以在最后检查候选计数我们将执行O(k)操作。

1 个答案:

答案 0 :(得分:2)

这不起作用。在数组开头显示aint(n/k + 1)次,然后随机混合n-int(n/k+1)个不再包含a的数字。由于n-int(n/k+1)的{​​{1}}大于k>2,因此无法保证int(n/k+1)的数组条目不会降至零。

此算法的改进版本不会产生假阴性(但会产生误报),请参阅Data Streams: Algorithms and Applications By S. Muthukrishnan,第5.1.2节“频繁元素/重击中”。