题目:
题目要求:
它的最大子序列很显然是 { 2,3 }
第一种方法蛮力法(强制枚举):
所以我们需要在没加一个就更新最大的子序列,当加到最后一个元素时
我们用举例图片来描述一下我们的蛮力法:
在第二次从第二个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)
在第四次从第四个元素开始时候,我们的最大子序列和是依次动态更新为 6
在第六次从第六个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)
综上:蛮力法的结果为 最大子序列为{ 5,-4,3,2 },最大子序列和为 6
作为一个程序猿,我们在代码的时间复杂度为n平方时,我们要很自觉的要想到对复杂度进行降级,当n的数字变大时,n的平方就会以倍速增长,
即使不能降到那么低也要考虑试试能不能降到 n log 2^n
二.分而治之(分治法):
分治法,字面意思是“分而治之”,就是把一个复杂的1问题分成两个或多个相同或相似的子问题,再把子问题分成更小的子问题直到最后子问题可以简单地直接求解,原问题的解即子问题的解的合并,这个思想是很多高效算法的基础,
- 先把一个大问题有规律有技巧的分为小问题
- 对小问题进行计算,按要求求解(此方法的解决思想是解决小问题比直接解决大问题要简单)
- 再把计算好的结果或答案,按要求进行组合归并
基于这个算法还衍生了很多其它算法:但是并未完全使用到它的思想,都只用了一部分
1.二分查找:利用了 分解问题和计算问题的思想
此题的分治法解决思路:
当划分到最小单元以后,左右两边都能计算出一个最大的序列,这个序列在最底层还是只有一个元素的,所以长度为一,大小就是它自己,
如果合并序列比子序列大,那么合并序列才是最大子序列,反之,就看看左右两边那边的子序列大,大的就作为返回值,继续回溯,
我们给定一个序列,然后按照分而治之的思想一步一步的做:
第一步:把大问题拆解成一个个小问题
当图片上的步骤完成以后,我们的第一步也就完成了,把大问题花小,这个时候我们这些小序列中谁的大就返回到上一级
第二步:对小问题进行求解,向上一级带回自己所计算的参数
在合并计算时,左边会返回一个子序列的最大值,右边也会有一个,但是不一定合并后的子序列它们会是最大的序列和,我们要进行合并扫描
思考:大家可以想想为什么左右两边,都要从中间开始向两边扫描(思路是连续最小序列和)
第三步:把计算好的结果,按要求进行组合回溯(或参数回带)
它们在合并后又开始新的计算,只要合并到最高层以后就有了最后的结果
下面我们用伪代码来看看这个算法的实现:
这里都还好理解,对于左右两边要返回一个最大子序列和没问题,主要的重点在于,合并时怎么计算分界点是否才是那个最大子序列
我们试着构造一个序列 { 3,1,2,-2,6,1 },当回溯到最后一次拆分时,
右边的最大子序列和是:6+1=7
然后就是右边区域,它需要从-2开始向右边扫描,扫描完成以后的值是: -2+6+1=5
综上:
所以这个全序列才能构成最大的子序列和,并不是左右两边的数据构成的
由于分治法的时间开销主要是,拆分和合并,所以计算方法也有点不同
三.在线处理算法(Online Algorithm)
在线处理(Online Algorithm)是一种在数据流到达时实时处理数据的算法。在线处理算法需要在没有全部数据的情况下,即时处理当前接收到的数据,并根据已有的局部信息做出相应的决策,同时保证最终的全局结果是正确的。
这一题我们使用在线处理算法的思路:
当加到某个元素为负数时,这时候直接清零,从这个元素开始从新记录,因为负数不管后面元素是什么,都只会让这个子序列和变小
而且它只能执行依次,不可重复用,比如给它一串数据,它的执行逻辑是扫描完一个就会丢掉,尤其是清零时候,前面的数据原值直接就全部没有了
四.动态规划
我们说了,在线处理已经把时间复杂度降到完美了,所以我们这里的动态规划就作为一个拓展,动态规划的时间复杂的根据所给的题目有关,是不稳定的 常见的有:O(n^2 , O(n^3
什么是动态规划?
以上定义来自维基百科,看定义感觉还是有点抽象。简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。
我们简单的构造一个例子来描述一下这道题:
动态规划的灵魂在于,他会记录每一次计算的结果,避免了重复计算,后面新增的数据计算,都会基于它的前一次计算结果
五.总结
算法和数据结构是相辅相成的,只有选定了数据结构,才能依据作出相应的算法
————————————博客根据—浙江大学陈越老师的《数据结构》课程总结