您的位置:首页 > 其它

最大子序列问题

2016-07-29 00:00 211 查看
问题1:输入是具有n个浮点数的向量x,输出这个向量的任何连续子向量中的最大和。当所有元素为负数时定义最大和为0。
(1)穷举算法:对所有0<=i<=j<n的整数对进行迭代。对每个整数对(i,j),程序都要计算x[i...j]的总和,并判断其是否大于当前的最大总和。

maxsofar=0
for i=[0,n)
for j=[i,n)
sum=0
for k=[i,j]   /* sum is sum of x[i...j] */
sum+=x[k]
maxsofar=max(maxsofar,sum)


可见这个算法运行时间为O(n**3)。
(2)平方算法1:从(1)中可以看出,x[i...j]的总和与前面已计算出的总和x[i...j-1]密切相关。利用这一点进行改进。

maxsofar=0
for i=[0,n)
sum=0;
for j=[i,n)
sum+=x[j]  /* sum is sum of x[i...j] */
maxsofar=max(maxsofar,sum)


这个算法的效率为O(n**2)。
(3)平方算法2:通过访问在外循环执行之前就已经构建的数据结构,在内循环中计算总和。cumarr[i]表示x[0...j]的总和,因此x[i...j]的总和可通过cumarr[j]-cumarr[i-1]获得。

cumarr[-1]=0
for i=[0,n)
cumarr[i]=cumarr[i-1]+x[i]
maxsofar=0
for i=[0,n)
for j=[i,n)
sum=cumarr[j]-cumarr[i-1]  /* sum is sum of x[i...j] */
maxsofar=max(maxsofar,sum)


(4)分治算法:要解决规模为n的问题,可递归地解决两个规模近似为n/2的子问题,然后对两个结果进行合并以得到整个问题的答案。将x划分为两个近似相等的子向量ab,在a和b中分别找出总和最大的子向量ma和mb,然后找到跨越a和b边界的最大子向量mc,返回三个总和中的最大者。通过观察发现mc在a中的部分是a中包含右边界的最大子向量,mc在b中的部分是b中包含左边界的最大子向量。伪代码如下:

float maxsum(l,u)
if(l>u)  return 0  /* zero elements */
if(l==u)  return max(0,x[1])  /* one element */
m=(l+u)/2
lmax=sum=0;
for(i=m;i>=l;i--)  /* find max crossing to left */
sum+=x[i]
lmax=max(lmax,sum)
rmax=sum=0
for i=(m,u]  /* find max crossing to right */
sum+=x[i]
rmax=max(rmax,sum)
return  max(lmax+rmax,maxsum(l,m),maxsum(m+1,u))


(5)扫描算法:我们采用从x[0]开始扫描,一起到最右端x[n-1],并记下所遇到的最大子向量总和(初始值设为0)。假设我们已解决了x[0,i-1]的问题,如何将其扩展到x[0...i]呢?前i个元素中,最大总和子数组要么在前i-1个元素中(用maxsofar存储),要么其结束位置为i(用maxendinghere存储)。

maxsofar=0
maxendinghere=0
for i=[0,n)
maxendinghere=max(maxendinghere+x[i],0) /* 计算前maxendinghere是结束位置为i-1的最大子向量的和 */
maxsofar=max(maxsofar,maxendinghere)


该算法十分简短,运行时间为O(n)。
两个平方算法和扫描算法都使用了简单的动态规划形式,通过使用一些空间来保存蹭计算结果,避免了花时间对其重复计算。平方算法2使用了一个累积表来存放x[0...i]的总和。与数组与数组相关的问题经常可以通过思考“如何将x[0...i-1]的解扩展为x[0...i]的解?"来解决。
问题2:假设我们想要查找的是总和最接近0的子向量,而不是具有最大总和的子向量,该如何设计算法?
可初始化累加数组cum,使得cum[i]=x[0]+...+x[i]。如果cum[l-1]=cum[u],那么子向量x[l...u]之和就为0.因此可以通过定位cum中最接近的两个元素来找出和最接近0的子向量。这可以通过排序数组,在O(nlogn)时间内完成。
关键算法设计思想:穷举策略、动态规划(保存状态,避免重复计算)、分治策略、扫描策略(如何将x[0...i-1]的解扩展到x[0...i]的解)、累积表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: