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

时间:2011-03-04 15:07:05

标签: arrays algorithm

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

2 个答案:

答案 0 :(得分:13)

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

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

要计算子阵列的任何平均值,请计算对应于结束索引的对应总和与对应于起始索引的对应度的差异,并除以子阵列中的条目数。例如,对于i+1j的范围,请执行

average = (b[j] - b[i]) / (double)(j - i);

通过计算沿两个轴的累积和,同样的事情在两个维度上起作用。

答案 1 :(得分:1)

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

编辑:恒定时间平均法并非“非常接近”;可以在数学上证明,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

再次编辑:糟糕:我的解决方案适用于多维锯齿状阵列。好的,没什么大不了的。在这种情况下,我将创建一个数组,其中包含从第一个到当前的所有元素的每个元素的累积和。然后,要计算任何连续子阵列的平均值,从结束索引的累积和中减去起始索引之前的元素(或从第一个索引开始时为零)的累积和,并除以之间的差值。开始和结束索引加1。

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