如何快速找到最大平均间隔?

时间:2012-08-26 06:56:03

标签: algorithm

从整数数组A[N],我想找到一个间隔最大[i,j]的间隔(A[i] + A[i + 1] + .. + A[j]) / (j - i + 1)

时间间隔(j - i + 1)的长度应大于L(L >= 1)

我想的是计算每个i~j的平均值,但这样做太慢了。(N太大了)

算法是否比O(N^2)更快?或者我想知道是否存在随机方法。

1 个答案:

答案 0 :(得分:10)

O(N*logC)算法,其中C与数组的最大元素值成比例。与近期论文中一些比较复杂的算法相比,该算法更易于理解,可以在短时间内实现,并且在实际中仍然足够快。

为简单起见,我们假设数组中至少有一个非负整数。

该算法基于二进制搜索。首先,我们可以发现最终答案必须在[0, max(A)]范围内,并且我们在每次迭代中将这个间隔减半,直到它足够小(例如10 -6 )。在每次迭代中,假设可用间隔为[a,b],我们需要检查最大平均值是否不小于(a+b)/2。如果是这样,我们会得到较小的时间间隔[(a+b)/2, b],否则我们会得到[a, (a+b)/2]

现在问题是:给定一个数字K,如何检查最终答案是否至少为K

假设平均值至少为K,则存在ij(A[i] + A[i+1] + ... + A[j]) / (j - i + 1) >= K。我们将两边乘以(j-i+1),然后将右边移到左边,我们得到(A[i] - K) + (A[i+1] - K) + ... + (A[j] - K) >= 0

所以,让B[i] = A[i] - K,我们只需找到[i, j]j - i + 1 > L)的间隔,即B[i] + ... + B[j] >= 0。现在的问题是:给定数组B和长度L,我们要找到一个长度大于L的最大和的区间。如果最大总和为>= 0,则原始平均数K是可能的。

第二个问题可以通过线性扫描解决。设sumB[0] = 0sumB[i] = B[1] + B[2] + ... + B[i]。对于每个索引i,在B[i]结束的最大和间隔为sumB[i] - min(sumB[0], sumB[1], ..., sumB[i-L-1])。在增加i的情况下扫描数组时,我们可以动态保持min(sumB[0], ..., sumB[i-L-1])

子问题的时间复杂度为O(N)。我们需要O(logC)次迭代,因此总复杂度为O(N*logC)

P.S。这种“平均问题”属于一类称为fractional programming的问题。类似的问题是最小平均加权生成树,最小平均加权周期等。

P.S。再次。 O(logC)是一个松散的界限。我认为我们可以通过一些仔细的分析来减少它。