给定大小为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)操作。
答案 0 :(得分:2)
这不起作用。在数组开头显示a
次int(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节“频繁元素/重击中”。