免责声明:我知道这个问题可以通过单一传递非常有效地解决,但我有兴趣用分而治之的方式做到这一点,因为它与我们解决的典型问题有点不同并征服。
假设给出一个大小为n且间隔长度为l的浮点数组X [1:n]。问题是设计一个分而治之的算法,从具有最大总和的数组中找到长度为l的子数组。
这是我想出的。对于长度为n的数组,有l个连续元素的n-1 + 1个子数组。例如,对于长度为n = 10且l = 3的数组,将有8个长度为3的子阵列。
现在,为了将问题分成两半,我决定在n-l + 1/2处打破数组,以便将相同数量的子阵列分配到我的分区的两半,如下面的算法所示。同样,对于n = 10,l = 3,n-1 + 1 = 8,所以我将问题除以(n-1 + 1)/ 2 = 4.但对于第4个子阵列,我需要数组元素达到6即(n + l-1)/ 2。
void FixedLengthMS(input: X[1:n], l, output: k, max_sum)
{
if(l==n){//only one sub-array
sum = Sumof(X[1:n]);
k=1;
}
int kl, kr;
float sum_l, sum_r;
FixedLengthMS(X[1:(n+l-1)/2], l, kl, sum_l);
FixedLengthMS(X[(n-l+3)/2:n], l, kr, sum_r);
if(sum_l >= sum_r){
sum = sum_l;
k = kl;
}
else{
sum = sum_r;
k = n-l+1/2 + kr;
}
}
注意:清除数组索引 对于从(n-1 + 1)/ 2开始的子阵列,我们需要数组元素达到(n-1 + 1)/ 2 + l-1 =(n + l-1)/ 2
我的担忧: 为了应用分而治之,我在两个数组中都使用了一些数据元素,所以我正在寻找另一种避免额外存储的方法。
更快的方法将不胜感激。
请忽略代码部分的语法,我只想概述算法。
答案 0 :(得分:0)
你不需要分而治之。可以使用简单的单程算法来完成任务。让我们假设,该阵列足够大。然后:
double sum = 0;
for (size_t i = 0; i < l; ++i)
sum += X[i];
size_t max_index = 0;
double max_sum = sum;
for (int i = 0; i < n - l; ++i) {
sum += X[i + l] - X[i];
if (sum > max_sum) {
max_sum = sum;
max_index = i;
}
}