我正在寻找一种数据结构,我可以在给定的可变范围内找到最常出现的数字(在一组数字中)。
让我们考虑以下基于1的数组:
1 2 3 1 1 3 3 3 3 1 1 1 1
如果我查询范围(1,4),数据结构必须重新调整1,这将发生两次。 其他几个例子:
(1,13)= 1
(4,9)= 3
(2,2)= 2
(1,3)= 1(所有1,2,3都出现一次,所以返回第一个/最小的一个。此时不那么重要)
我搜索过,但找不到类似的东西。我正在寻找(理想情况下)具有最小空间要求,快速预处理和/或查询复杂性的数据结构。
提前致谢!
答案 0 :(得分:1)
设N是数组的大小,M是该数组中不同值的数量。
我正在考虑两个复杂性:预处理和查询大小为n的区间,每个区间必须是空间和时间的。
<小时/> 解决方案1:
没有预处理,我们会查看间隔的所有值并找到最常用的值。
<小时/> 解决方案2:
对于数组的每个位置,我们有一个累积数组,它给出了每个值x,x在该位置之前的数组中的x次。
给定一个区间,我们只需要每个x减去2个值来找到该区间中的x个数。我们迭代每个x并找到最大值。如果n < M我们遍历区间的每个值,否则我们迭代x的所有可能值。
<小时/> 解决方案3:
对于每个值x,构建数组中存在x的所有位置的二进制堆。堆中的键是位置,但是您还存储了此位置和数组开头之间的x总数。
给定一个区间,我们只需要每个x减去2个值来找到该区间中的x个数:在O(log(N))中我们可以要求x的堆在开始之前找到两个位置/间隔结束并减去数字。基本上它比直方图需要更少的空间,但现在查询在O(log(N))中。
答案 1 :(得分:0)
您可以创建二进制分区树,其中每个节点表示{value - &gt;的直方图。对于给定范围,有两个子节点,表示范围的上半部分和下半部分。
然后查询只是递归地将少量这些直方图加在一起以覆盖所需的范围,并扫描结果直方图一次以找到最高发生次数。
有用的优化包括:
更新:我对算法复杂性的思考,假设在整个范围内有少量可能的值M和总共N个值: