如何使用分而治之的方法来解决“固定大小最大子阵列”?

时间:2016-10-10 20:44:28

标签: algorithm divide-and-conquer

免责声明:我知道这个问题可以通过单一传递非常有效地解决,但我有兴趣用分而治之的方式做到这一点,因为它与我们解决的典型问题有点不同并征服。

假设给出一个大小为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

我的担忧: 为了应用分而治之,我在两个数组中都使用了一些数据元素,所以我正在寻找另一种避免额外存储的方法。

更快的方法将不胜感激。

请忽略代码部分的语法,我只想概述算法。

1 个答案:

答案 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;
    }
}