数据结构与算法之一道题感受算法(算法入门)

这篇具有很好参考价值的文章主要介绍了数据结构与算法之一道题感受算法(算法入门)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目:

给定N个整数的序列{ A1,A2,....An },求函数F(i,j)=Max{ Ai+.....Aj  }

题目要求:

这道题的目的是要求给定的一个整数序列中,它所含的连续子序列的最大值,比如现在我有一个整数序列{ -3,2,3,-3,1}

它的最大子序列很显然是  { 2,3 }

第一种方法蛮力法(强制枚举):

我们从第一个整数开始遍历,依次计算一个一个的加起来,知道最后一个元素,我们不断的往后加的时候会一直更新最大的子序列,有情况是从头加到尾不是最大的,它在中间就已经是最大的

所以我们需要在没加一个就更新最大的子序列,当加到最后一个元素时

就换一个元素开始,比如从第二个元素开始,完了就第三个,就这么一直换了换的加,一直到使用最后一个元素开始计算时就结束

我们用举例图片来描述一下我们的蛮力法:

数据结构与算法之一道题感受算法(算法入门)

 文章来源地址https://www.toymoban.com/news/detail-444210.html

 

在第一次从第一个元素开始时候,我们的最大子序列和是依次动态更新为 1 ,3 ,5 ,6

在第二次从第二个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)

在第三次从第三个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)

在第四次从第四个元素开始时候,我们的最大子序列和是依次动态更新为 6

在第五次从第五个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)

在第六次从第六个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)

在第七次从第七个元素开始时候,我们的最大子序列和是依次动态更新为 (未更新)

综上:蛮力法的结果为 最大子序列为{ 5,-4,3,2 } ,最大子序列和为 6

现在我们使用伪代码实现一下这个算法:

数据结构与算法之一道题感受算法(算法入门)

 我们可以根据这个伪代码很快的计算出它的时间复杂度,有两个for循环,很明显的就是T(n) = O(n^2)

作为一个程序猿,我们在代码的时间复杂度为n平方时,我们要很自觉的要想到对复杂度进行降级,当n的数字变大时,n的平方就会以倍速增长,

所以,我们要考虑把这个复杂度降到 n log 2^n  ,或者更好的  n 级 ,还有 log n

即使不能降到那么低也要考虑试试能不能降到 n log 2^n

二.分而治之(分治法):

首先我们来了解一下什么是分而治之?

分治法,字面意思是“分而治之”,就是把一个复杂的1问题分成两个或多个相同或相似的子问题,再把子问题分成更小的子问题直到最后子问题可以简单地直接求解,原问题的解即子问题的解的合并,这个思想是很多高效算法的基础,

这个算法的简单思路就是:

  • 先把一个大问题有规律有技巧的分为小问题
  • 对小问题进行计算,按要求求解(此方法的解决思想是解决小问题比直接解决大问题要简单)
  • 再把计算好的结果或答案,按要求进行组合归并

基于这个算法还衍生了很多其它算法:但是并未完全使用到它的思想,都只用了一部分

最耳熟能详的就是:

1.二分查找:利用了 分解问题和计算问题的思想

2.归并排序:利用了 计算问题和合并求解的思想

此题的分治法解决思路:

这里,我们对于这个整数序列就可以使用这样的方法,我们先把这个序列一直划分,划分到左右两边要么只有一个元素要么只有一个元素的时候就可以计算了,

当划分到最小单元以后,左右两边都能计算出一个最大的序列,这个序列在最底层还是只有一个元素的,所以长度为一,大小就是它自己,

然后就回溯,回溯的过程中我们可能存在两个序列组合后才是最大的情况,所以我们要对其合并后的序列进行扫描,看看合并的序列比未合并的序列是否要大一些

如果合并序列比子序列大,那么合并序列才是最大子序列,反之,就看看左右两边那边的子序列大,大的就作为返回值,继续回溯,

直到回溯到最开始调用函数的时候,函数就执行完成,这个返回值就是最大子序列和

我们给定一个序列,然后按照分而治之的思想一步一步的做:

第一步:把大问题拆解成一个个小问题

数据结构与算法之一道题感受算法(算法入门)

 如图:我们把一个七元素的序列,划分成了七分只有一元素的子序列

当图片上的步骤完成以后,我们的第一步也就完成了,把大问题花小,这个时候我们这些小序列中谁的大就返回到上一级

第二步:对小问题进行求解,向上一级带回自己所计算的参数

数据结构与算法之一道题感受算法(算法入门)

在计算的时候:一定要保证数据已经到达最小单位,比如这里我们是一个数组的话,那每一个最小序列必须是单个的数组元素以后才能计算

在合并计算时,左边会返回一个子序列的最大值,右边也会有一个,但是不一定合并后的子序列它们会是最大的序列和,我们要进行合并扫描

合并扫描左边区域和右边区域的扫描都要从中间断点开始,然后将扫描出的结果和左边返回值,右边返回值对比,大的才是这次划分的最终答案

思考:大家可以想想为什么左右两边,都要从中间开始向两边扫描(思路是连续最小序列和)

第三步:把计算好的结果,按要求进行组合回溯(或参数回带)

数据结构与算法之一道题感受算法(算法入门)

 如图,从最低层开始,我们只要把左右两边的结果计算出来以后就已经开始合并了,每次拆分都对应着一次合并,

它们在合并后又开始新的计算,只要合并到最高层以后就有了最后的结果

下面我们用伪代码来看看这个算法的实现:

数据结构与算法之一道题感受算法(算法入门)

 分治法在开始的时候会不断的拆分,当left = = right的时候,说明这数据下标就是它自己,就达到了我们要求的最小元素的要求,就可以计算后回带了

这里都还好理解,对于左右两边要返回一个最大子序列和没问题,主要的重点在于,合并时怎么计算分界点是否才是那个最大子序列

所以这里我们特别讲解一下这个左右扫描的思路:

我们试着构造一个序列  { 3,1,2,-2,6,1 },当回溯到最后一次拆分时,

左边的最大子序列和是: 3+1+2 =6

右边的最大子序列和是:6+1=7

结果 7 不一定是最后的总的最大子序列和,我们这个时候就来扫描一下,左边的区域要从 2 开始向 左边扫描  然后实时更新最大序列和,很显然扫描完成以后最大序列和是: 2+1+3=6

然后就是右边区域,它需要从-2开始向右边扫描,扫描完成以后的值是: -2+6+1=5

最后左右关联起来的最大子序列和为 :5+6=11

综上:

11 > 7 >6

所以这个全序列才能构成最大的子序列和,并不是左右两边的数据构成的

数据结构与算法之一道题感受算法(算法入门)

 

以上就是分治法的解题思路了,我们一起来看看分治法的时间复杂度是多少吧

由于分治法的时间开销主要是,拆分和合并,所以计算方法也有点不同

我们可以简单的看一下,每拆分一次,左边右边都需要花费T(n/2)的时间,然后每次合并的扫描时间 就是O(n)也就是扫描会把每个被合并的元素一个一个都遍历一遍

数据结构与算法之一道题感受算法(算法入门)

 所以,最后分治法解决这一道题的时间复杂度是:O(N log N)

三.在线处理算法(Online Algorithm)

在线处理(Online Algorithm)是一种在数据流到达时实时处理数据的算法。在线处理算法需要在没有全部数据的情况下,即时处理当前接收到的数据,并根据已有的局部信息做出相应的决策,同时保证最终的全局结果是正确的。

在线处理算法就很神奇,它好像活得一样,不管你输入的数据有没有输完,它总能根据已输入的数据先做出判断然后给出答案,感觉有和贪婪算法一样,以局部最优解以定全局最优解

这一题我们使用在线处理算法的思路:

从第一元素开始遍历,依次向后加上后面的元素,当我们的加到后面的元素,所计算的结果集还是整数,就一直和已经记录的最大值比较,时刻记录着最大值,

当加到某个元素为负数时,这时候直接清零,从这个元素开始从新记录,因为负数不管后面元素是什么,都只会让这个子序列和变小

从新记录的是当前最大值,我们在前面记录的最大值还存在,要是从新记录的最大值是比原来的大,依旧可以更新最终的最大值

数据结构与算法之一道题感受算法(算法入门)

 在线处理的有点很明显它的处理速度很快时间复杂度达到了O(n),对于任何一种算法来说,我们至少要把数据遍历一遍,所以这个算法已经算是最优的了

数据结构与算法之一道题感受算法(算法入门)

 在线处理方法实现比较简单,运行速度快,也会导致它的正确性不是很明显

而且它只能执行依次,不可重复用,比如给它一串数据,它的执行逻辑是扫描完一个就会丢掉,尤其是清零时候,前面的数据原值直接就全部没有了

我们可以思考一下:这种算法的会不会发生错误?或者它能保证不管任何整数序列都可以拿到正确的最大序列和吗?

四.动态规划

我们说了,在线处理已经把时间复杂度降到完美了,所以我们这里的动态规划就作为一个拓展,动态规划的时间复杂的根据所给的题目有关,是不稳定的 常见的有:O(n^2) , O(n^3)

但是如果能构造到最优解,也可以达到 O(n)

什么是动态规划?

动态规划(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

以上定义来自维基百科,看定义感觉还是有点抽象。简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。

再具体一点,它会把算过的值记住,然后下一个计算可能会基于这个值来计算,减少了重复的计算,原始数据只会计算一次,每多一个数据,都是基于已经计算过的结果计算,新值 + 已经计算过的值

我们简单的构造一个例子来描述一下这道题:

数据结构与算法之一道题感受算法(算法入门)

 对于这道题来说,刚好利用动态规划的时间复杂度也是O(n)

动态规划的灵魂在于,他会记录每一次计算的结果,避免了重复计算,后面新增的数据计算,都会基于它的前一次计算结果

以此,我们对于动态规划的使用就要基于此点

五.总结

算法和数据结构是相辅相成的,只有选定了数据结构,才能依据作出相应的算法

所以,在学算法前,数据结构的知识也要有

 

————————————博客根据——浙江大学陈越老师的《数据结构》课程学习笔记

 

到了这里,关于数据结构与算法之一道题感受算法(算法入门)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构之树与二叉树——算法与数据结构入门笔记(五)

    本文是算法与数据结构的学习笔记第五篇,将持续更新,欢迎小伙伴们阅读学习。有不懂的或错误的地方,欢迎交流 前面章节介绍的都是线性存储的数据结构,包括数组、链表、栈、队列。本节带大家学习一种非线性存储的数据结构,即树(tree)。 不管是在面试时,还是日

    2024年02月08日
    浏览(25)
  • 算法与数据结构(十)--图的入门

    图是由一组顶点和一组能够将两个顶点连接的边组成的。 按照连接两个顶点的边的不同,可以把图分为以下两种: 无向图:边仅仅连接两个顶点,没有其他含义; 有向图:边不仅连接两个顶点,并且具有方向; 另外图还可以分为赋权图和非赋权图,一个是每条边都带有权值

    2024年02月11日
    浏览(21)
  • 【算法入门必刷】数据结构-栈(一)

    📦个人主页:一二三o-0-O的博客 🏆技术方向:C/C++客户端资深工程师(直播+音视频剪辑) 👨‍💻作者简介:数据结构算法与音视频领域创作者 📒 系列专栏:牛客网面试必刷 📣专栏目标:帮助伙伴们通过系统训练,掌握数据结构与算法,收获心仪Offer 📝推荐一个找工作

    2024年02月13日
    浏览(42)
  • 算法与数据结构(五)--二叉树入门

    符号表的增删查操作,随着元素个数N的增多,其耗时也是线性增多的,时间复杂度都是O(n),为了提高运算效率,我们学习树这种数据结构。 目录 一.树的基本定义 二.树的相关术语 三.二叉树的基本定义 四.二叉树的链表实现 1.二叉树结点类 结点类API设计:​编辑 代码实现:

    2024年02月12日
    浏览(23)
  • 数据结构与算法十一 图的入门

    在现实生活中,有许多应用场景会包含很多点以及点点之间的连接,而这些应用场景我们都可以用即将要学习的图这种数据结构去解决。 地图: 我们生活中经常使用的地图,基本上是由城市以及连接城市的道路组成,如果我们把城市看做是一个一个的点,把道路看做是一条

    2024年02月04日
    浏览(54)
  • 数据结构与算法入门书籍推荐(15本)

    1.《算法图解》 本书适合刚开始学习算法的初学者,它使用非常通俗易懂的语言,详细解释了各种基础算法的实现方法,包括快速排序、图论、动态规划和贪心算法等。 2.《算法导论》 这是一本通用的算法指南,涵盖了所有重要的算法和数据结构。尽管它可能对初学者来说过

    2024年02月11日
    浏览(24)
  • 【数据结构与算法】掌握顺序栈:从入门到实践

       🌱博客主页:青竹雾色间. 🌱系列专栏:数据结构与算法 😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注 目录 前言 顺序栈的实现 初始化栈 判断栈空 判断栈满 入(进)栈 出栈 获取栈顶元素 示例代码 顺序栈的应用前景 当你学习数据结构和算法时,顺序栈(Sequential

    2024年02月08日
    浏览(46)
  • 【算法与数据结构】1 算法0基础入门,详解什么是算法?什么是线性查找法?

    欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于算法与数据结构体系专栏, 本专栏 是服务于0基础者,一起完成从0到1的跨越 就是 一系列 可以解决问题的 清晰的 可执行的 计算机指令 那么生活中有哪些算法? 问路 :坐公交车到

    2023年04月09日
    浏览(32)
  • 【数据结构入门精讲 | 第九篇】考研408排序算法专项练习(一)

    前面几篇文章介绍的是排序算法,现在让我们开始排序算法的专项练习。 1.希尔排序是稳定的算法。(错) 解析:稳定性是指如果两个元素在排序前后的相对顺序保持不变,那么这个排序算法就是稳定的。对于具有相同的元素,排序后它们的相对位置应该保持不变。

    2024年02月03日
    浏览(26)
  • 【数据结构 | 入门】线性表与链表 (问题引入&实现&算法优化)

    🤵‍♂️ 个人主页: @计算机魔术师 👨‍💻 作者简介:CSDN内容合伙人,全栈领域优质创作者。 本文是浙大数据结构学习笔记专栏 这里我们引入一个问题,最常见的多项式,我们如何使用编程将多项式表示出来呢? 我们可以使用数组来表示,但是会随着一个问题,如下图底

    2024年01月21日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包