找出数组中两段不相交的子数组,使其差值最大
2013-10-29 10:55
239 查看
问题描述:
Givenanarrayofintegers.Findtwodisjointcontiguoussub-arrayssuchthattheabsolutedifferencebetweenthesumoftwosub-arrayismaximum.
*Thesub-arraysshouldnotoverlap.
eg-[2-1-21-428]ans-(-1-21-4)(28),diff=16
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]
相关文章推荐
- zookeeper清除日志文件工具
- 等差数列连续异或模板
- js--table样式插件[隔行换色、复选框操作、光标]
- CAD Import .NET支持AutoCAD DWG 2013
- 打开文件的shell脚本
- 「垃圾人定律」
- 10款极具人气的PHP开源工具
- test
- 解析#ImageView之ScaleType属性#
- PHP apache2.2 mysql 的安装
- MyEclipse 10 中增加svn插件
- ANDROID笔记:Activity之间的传值
- oracle在线日志文件分析
- 《抽象是一种美》
- 视频播放器实现技术(二)
- 【discuzx2】space_doing.htm
- 从零开始学WCF(13)事务
- 字符串循环左移
- Ural1024 Permutations
- 外媒曝:暴雪《炉石传说》或登陆安卓和WP平台