Algorithm 如何快速找到最大平均间隔?
从整数数组Algorithm 如何快速找到最大平均间隔?,algorithm,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)更快的算法?或者我想知道是否存在一种随机方法。有一种O(N*logC)算法,其中C与数组的最大元素值成比例。与近年来一些较为复杂的算法相比,该算法易于理解,实现时间短,在实际应用中仍然具有足够的速度 为简单起见,我们假设数组中至少有一个非负整数
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)
更快的算法?或者我想知道是否存在一种随机方法。有一种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
,存在一些i
,j
,使得(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]=0
,sumB[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)
另外,这类“一般问题”属于一类问题,称为。类似的问题有最小平均加权生成树、最小平均加权环等
再说一遍。O(logC)
是一个松散的绑定。我想我们可以通过一些仔细的分析来减少它。你能举一个简短的例子吗?你需要L>=2,对于L>=1,你可以返回[I,I],其中I是最大值index@barak1412:我相信他的意思是L
是动态地给算法指定的一个参数。我不是那样理解的。他最好给出一些例子,一个O(N)算法是由Goldwasser等人在年报道的。你可以下载该论文的pdf文件。你也可以在这里找到一个O(N*logL)1:+1这在第一次阅读中没有被理解,但是你已经很好地解释了它。另外,阅读这个链接的答案也帮助了我:为什么sumB[0]=0
?我尝试实现该解决方案,我认为应该将sumB[0]分配给B[0]。你能澄清一下吗?