一维向量中查找任何相邻子向量的最大和
2010-08-02 22:02 Aga.J 阅读(1598) 评论(5) 编辑 收藏 举报今天看到《编程珠玑》的第八章,里面提出了这个问题:
文章给了四种不同级别的算法,从n的三次方的时间开销到n的时间开销,在给出第2种算法(只需要n的平方,并且我第一次做的话也是这种做法)后,文章问读者能不能给出更快速的方法,于是我放下了书,自己想了想:
一开始想到的是一个递归的算法,每次遇到负数时都跳过,直到再次遇到正数,这时候已经形成了递归子式,然后递归返回是什么呢?就是拿递归子式和进行该递归前的所有负数之和进行比较,如果它们之和大于零则继续递归返回,如果小于零则抛弃。
但是这个算法实现起来比较麻烦,要记录的现场比较多,然后就继续想了想,突然想到,要是向量总是从负数开始,那么前面的负数在一开始就不用考虑,所有就有了抛弃前置负数和抛弃后置负数的想法(抛弃后置负数其实也就是抛弃前置负数,只要把向量顺序逆一下就是同个道理了),但是发现这样的话又得用递归,因为虽然抛弃了前后的负数,但是中间还再需要进行这样的抛弃。
最后,在抛弃前置和后置负数的基础上,我得到了下面这样的解法
int max=0;
int temp=0;
for(int k=9;k>=0;k--)
{
temp=i[k]+temp;
if(temp<0)temp=0;
else max=getMax(max,temp);
}
cout<<max;
这里利用的是后置负数的好处,将后置的负数从后往前抛弃,然后记得记录下当前最大数,因为在前面可能会加上一个负数而没被纳入抛弃的范围。这种方法的时间复杂度和书里面介绍的最后一种方法是一样的,都是n的大O,而书里给出的算法名词是扫描算法,也有这种意思在里面吧。
最后,我该休息了,我想既然能用到后置负数的好处,那么前置负数的好处也能用上,因为“后置”就是“前置”嘛,不过还需要考虑前后这样的扫描的终止情况,怎么又觉得有点双向冒泡的感觉了。。。
作者:Aga.J
出处:http://www.cnblogs.com/aga-j
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
个人学习笔记仅供本人记录知识所用,不属发表性文章。