您的位置:首页 > 其它

找出数组中两段不相交的子数组,使其差值最大

2013-10-29 10:55 239 查看
问题描述:


Givenanarrayofintegers.Findtwodisjointcontiguoussub-arrayssuchthattheabsolutedifferencebetweenthesumoftwosub-arrayismaximum.
*Thesub-arraysshouldnotoverlap.
eg-[2-1-21-428]ans-(-1-21-4)(28),diff=16


解答:可在线性时间内解决。

思路:

以i为划分点将数组划分为A[1:i]和A[i+1,n]两个部分,统计第一个子数组中的最大子数组值a1和最小子数组值a3,统计第二个子数组中的最大子数组值a4和最小子数组值a2.

那么abs(a1-a2)以及abs(a3-a4)中最大的值就是划分为i时候的的最大值了。

算法步骤:

首先,从左到右。统计A[1:i]中数值和最大的子数组的数值,用A1[i]来表示。然后从右到左,统计A[j:n]中数值和最小的子数组的数值,用A2[j]来表示。注意此时的i就是划分点

其次,从左到右。统计A[1:i]中数值和最小的子数组的数值,用A3[i]来表示。然后从右到左,统计A[j:n]中数值和最大的子数组的数值,用A4[j]来表示。注意此时的i就是划分点

最后,统计abs(A1[i]-A2[i+1])以及abs(A3[i]-A4[i+1])中的最大值。那就是我们需要的啦。

时间复杂度说明:

为什么说上述算法是线性的呢?

我们注意到只要能说明“统计A[1:i]中数值和最大的子数组的数值,用A1[i]来表示”这一步是线性时间的,那么整个算法也就是线性的。

下面就来说明一下怎么统计这个。

max=0;temp=0;

[code]for(intk=1;k<=n;k++)
{

if(A[k]<=0)

{

A1[k]=max;

temp+=A[k];

}


else

{

a1=max+temp+A[k];

a2=A[k];


if(max<a1)max=a1;

if(max<a2)max=a2;

temp=0;A1[k]=max;

}


}

补充:2014-3-18,今天又看了这个问题,感觉应该不是线性的而是O(n*n),为社么了?因为子数组的切分点不止一个啊!

哈哈,有质疑是好的,也怪自己当时没仔细考虑,其实是这样的,我们可以把A[1:i]的结果保存下来,计算A[1:i+1]的时候就可以直接用了!!

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
章节导航