最大子序列问题

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值