Arrays 如何预处理整数数组以查找O(1)中任意子数组的平均值?

Arrays 如何预处理整数数组以查找O(1)中任意子数组的平均值?,arrays,algorithm,Arrays,Algorithm,这个问题重新表述了一个问题。由于这个原始问题对我来说太难了,我正在尝试解决一个更简单的问题:如何处理整数数组以在恒定时间内找到任何子数组的平均值。显然,我们可以在O(n^2)中处理所有子数组。有更好的解决方案吗?对于1d情况:计算数组的累积和,即。E给定数组a,定义b b[0] = a[0]; for (int i = 1; i < n; ++i) b[i] = b[i - 1] + a[i]; 通过计算沿两个轴的累积和,同样的事情也适用于二维。我将使用每个子数组的索引零(或锯齿

这个问题重新表述了一个问题。由于这个原始问题对我来说太难了,我正在尝试解决一个更简单的问题:如何处理整数数组以在恒定时间内找到任何子数组的平均值。显然,我们可以在
O(n^2)
中处理所有子数组。有更好的解决方案吗?

对于1d情况:计算数组的累积和,即。E给定数组
a
,定义
b

b[0] = a[0];
for (int i = 1; i < n; ++i)
    b[i] = b[i - 1] + a[i];

通过计算沿两个轴的累积和,同样的事情也适用于二维。

我将使用每个子数组的索引零(或锯齿数组第一维长度的新一维数组)来存储平均值,并在将元素添加到数组中时计算平均值。在给定N个项目的平均值和+1个项目的情况下,您可以计算N+1个项目的平均值,在固定时间内,通过将现有平均值与构成该平均值的N个项目进行加权。这意味着数组的填充仍然是线性的,一旦填充,索引内存中就会有平均值(实际上是常数时间检索)

编辑:恒定时间平均法不仅仅是“非常接近”;可以从数学上证明,N个项目的平均值乘以N,再加上另一个项目,再除以N+1,在一般情况下正好等于N+1个项目的平均值。集合S的平均值乘以其基数N等于集合S的和,因此对于任意基数为N的非空集合S:

avg(S) = sum(S) / count(S)
S' = S + {X}
avg(S') = sum(S') / count(S')
        = (sum(S) + X) / count(S')
        = ((avg(S) * N) + X) / count(S') //QED
再次编辑:Oops:我的解决方案是针对多维锯齿阵列。好吧,没什么大不了的。在本例中,我将创建一个数组,其中包含从第一个元素到当前所有元素的每个元素的累积和。然后,要计算任何连续子数组的平均值,请从结束索引的累积和中减去开始索引之前元素的累积和(如果从第一个索引开始,则为零),然后除以开始索引和结束索引之间的差值加1


。。。这就是斯文的答案。

通过迭代子数组来找到平均值的简单解决方案,它不是有
O(n)
?为什么
O(n^2)
?您可以通过计算每个可能子阵列的平均值来进行预处理…然后只需查找答案就可以得到O(1)。你从没说过关于记忆的事…:)@雪熊:预先计算所有Aubarray的平均值应该是O(n^2)。数组应该是动态的吗?i、 e.您可以在预处理步骤后更新数组?顺便说一句,您链接的页面的唯一注释有答案!您的
j
索引是独占的。我会让它包含在内,它将导致
average=(b[j]-b[I]+a[I])/double(j-I+1)
@Snowbear:不,我的
I
是独占的。实际上,最好将
b
的长度增加到
n+1
,并将
0
作为第一个条目。对于包含第0个条目的子阵列,当前版本需要特殊的外壳。答案是关于基本算法的,所以我省略了这些细节:)你能用这个方法在O(1)时间内找到任何子数组的平均值吗?哦。我读的问题是关于锯齿数组的,你想得到锯齿数组的一个子数组(第二维度元素)的平均值。
avg(S) = sum(S) / count(S)
S' = S + {X}
avg(S') = sum(S') / count(S')
        = (sum(S) + X) / count(S')
        = ((avg(S) * N) + X) / count(S') //QED