Performance 计算大型/大型数组中不同元素的数量
我有一个大数组,比如。。数组[7000]。在每个索引处都有一个介于0和9之间的数字。然后给定两个索引,比如x=100,y=105,我需要找到给定范围内不同元素的数量。 假定Performance 计算大型/大型数组中不同元素的数量,performance,algorithm,data-structures,Performance,Algorithm,Data Structures,我有一个大数组,比如。。数组[7000]。在每个索引处都有一个介于0和9之间的数字。然后给定两个索引,比如x=100,y=105,我需要找到给定范围内不同元素的数量。 假定 array[100]=1; array[101]=2; array[102]=1; array[103]=4; array[104]=7; array[105]=2; 这里不同元素的数目是4{即数字1,2,1,7}。 这可以通过在两个索引之间迭代并跟踪数字来计算。但我面临的主要问题是程序必须执行的查询数量非常大,即必须对数
array[100]=1;
array[101]=2;
array[102]=1;
array[103]=4;
array[104]=7;
array[105]=2;
这里不同元素的数目是4{即数字1,2,1,7}。
这可以通过在两个索引之间迭代并跟踪数字来计算。但我面临的主要问题是程序必须执行的查询数量非常大,即必须对数千个x和y值(比如10^6个查询)执行操作,在这种情况下,这种方法将变得非常低效。有什么更好的算法,我尝试在许多地方搜索它。您正在寻找分段树
从每个索引的值在0-1之间的问题开始,然后逐步向上。然后,您可以使用O(logn)时间回答查询,并使用O(nlogn)时间构建树。确定此解决方案不具有内存效率,但可用于计算O(1)中的查询 形成另一个7000x10的二维数组,其中每一行都是该条目的[0到9]计数 因此,每当您得到一个查询时,您只需减去行的相应索引即可得到[0..9]个数字的计数 检查哪些索引具有非零计数差。 例如,数组行可能如下所示:
A[36] = { 5, 4, 2, 1, 4, 3, 7, 8, 2, 1 }
A[38] = { 6, 4, 2, 1, 4, 3, 7, 8, 2, 2 }
Diff = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
所以在36和38之间有两个独特的元素(0和9)
例2:对于输入数组{1,2,3,2,4},矩阵A应为:
A[0] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }
A[1] = { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }
A[2] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }
A[3] = { 0, 1, 2, 1, 0, 0, 0, 0, 0, 0 }
A[4] = { 0, 1, 2, 1, 1, 0, 0, 0, 0, 0 }
所以对于[3]到[4],应该有一个唯一的元素(4)
所以对于[1]到[4],应该有3个唯一的元素(2,3,4)
编辑:我考虑了一个惯例,即A[1]到A[4]表示索引[2到4]中的唯一元素。如果需要,可以将其更改为1到4。那么,
Diff = { 0, 0, 2, 1, 1, 0, 0, 0, 0, 0 }
(同样是3个独特的元素)由于数字在0-9范围内,我们可以使用一些好的作弊方法
其主要思想是:在整数中使用位
i
,以指示数字i
的存在。所以{}变成0,{0}变成1,{1}变成2,{0,1}变成3,依此类推。向其中添加项目x
很容易,只需使用set |(1即可,因为您的瓶颈是查询时间,数组元素是0-9,这是我的解决方案,只需O(n)
A=[1,2,1,4,7,2,2]
p[A,0,0]=[0,1,0,0,0,0,0,0,0]
p[A,0,1]=[0,1,1,0,0,0,0,0,0,0]
p[A,0,2]=[0,2,1,0,0,0,0,0,0]
p[A,0,3]=[0,2,1,0,1,0,0,0,0,0]
p[A,0,4]=[0,2,1,0,1,0,0,1,0,0]
p[A,0,5]=[0,2,2,0,1,0,0,1,0,0]
p[A,0,6]=[0,2,3,0,0,0,0,0,0]
查询(A,1,4)=[0,1,0,1,0,0,0,0,0,1,0,0]=3+1=4
查询(A,4,6)=[0,0,2,0,0,0,0,0,0,0,0]=[0,0,0,1,0,0,0,0,0,0]=1+1=27000个条目听起来不是那么多。你不能预计算范围吗?或者预计算子范围。或者缓存已经完成的计算?我更关心的是查询的数量,它们将是10^6范围,其中数组可以是0到10000之间的任何值。不超过10000。如果你查询的数组是sa每次我,你都必须根据你的查询次数多次执行相同的查询。因此预计算或缓存会产生影响。数组每次都是相同的。@EbbeM.Pedersen 7000^2大约是10^7,因此每个查询都可以是唯一的。你能举个例子吗?@chill example添加。我认为这不起作用。这个数组{1,2,3,2,4}
应该是一个反例。例如,检查范围[3,4]
(两个不同的元素)和[1,4]
(三个不同的元素)。啊,对不起,我一开始误解了算法,没关系。将a[0]和a[4]放在一起,然后你觉得需要做点更改
Diff = { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 }
Diff = { 0, 0, 2, 1, 1, 0, 0, 0, 0, 0 }
Assume:
A = arr
P = {} (Hash or Dict)
P[A,0,-1] = [0,0,0,0,0,0,0,0,0,0]
For i = 0,len(A):
e = A[i]
P[A,0,i] = P[A,0,i-1] where P[A,0,i-1][e]++
Query(A,x,y)
res = 0
ax = P[A,0,x]
ay = P[A,0,y]
for i = 0,10
res += ay[i] - ax[i] > 1 ? 1 : ay[i] - ax[i]
return res + 1