【发布时间】:2017-02-19 08:35:44
【问题描述】:
免责声明:我知道这个问题可以通过数组的单次传递非常有效地解决,但我对分而治之很感兴趣,因为它与我们用分治解决的典型问题有点不同并征服。
假设给定一个大小为 n、区间长度为 l 的浮点数组 X[1:n]。问题是设计一种分治算法,从和最大的数组中找出长度为 l 的子数组。
这就是我想出的。对于长度为 n 的数组,有 l 个连续元素的 n-l+1 个子数组。例如长度为 n = 10 和 l = 3 的数组,将有 8 个长度为 3 的子数组。
现在,为了将问题分成两半,我决定在 n-l+1/2 处拆分数组,以便将相等数量的子数组分配到我划分的两半,如下面的算法所示。同样,对于 n = 10,l = 3,n-l+1 = 8,所以我将问题划分为 (n-l+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-l+1)/2 开始的子数组,我们需要数组元素直到 (n-l+1)/2 + l-1 = (n+l-1)/2
我的担心: 为了应用分而治之,我在两个数组中都使用了一些数据元素,因此我正在寻找另一种避免额外存储空间的方法。
将不胜感激更快的方法。
请忽略代码部分的语法,我只是想给出算法的概述。
【问题讨论】:
-
虽然最初的最大子数组问题实际上可以通过 D&C 很好地解决(这样做涉及计算,对于任何给定的间隔,不仅是该间隔中的最大子数组,还包括从左边缘开始的最大子数组间隔和最大子数组在右边缘结束;然后父问题可以使用其 2 个子问题的 3+3=6 个答案来计算其对这 3 个问题的答案),这个变体(即,长度 l 是固定的) ) 问题非常不适合 D&C。我不明白 O(n) 时间的 D&C 算法是如何可能的,除非你将 l 限制为 o(n)。
标签: algorithm divide-and-conquer