复习<<数据结构与算法——复杂度分析>>

学习数据结构与算法的目的为了提高代码的执行效率及降低代码所占用的存储空间,因此时间复杂度及空间复杂度是评估一个算法的重要因素。而关于这两者的分析统称为复杂度分析。复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。

  • 为什么需要复杂度分析?

我们知道,可以直接通过统计、监控,就可以直接得到算法执行的确切时间和占用的内存大小。这种评估算法执行效率的方法又称作事后统计法,既然有这种方法,那我们为什么还要做时间、空间复杂度分析呢?这是由于事后统计法具有很大的局限性:

  1. 测试结果非常依赖测试环境
  2. 测试结果受数据规模的影响很大

因此,我们需要一个不用具体的测试数据来测试,就可以粗略地估计算法的执行效率的方法——复杂度分析。

  • 复杂度分析的作用
  1. 复杂度分析为我们提供一个很好的理论分析方向,并且这与测试环境是无关的,能够帮助我们对算法有一个大致的认识,让我们知道,比如在最坏的情况下程序执行的效率如何,同时也能为我们定义一个统一的标准,我们可以描述一个算法的时间复杂度是O(1),O(logn)等等。
  2. 但是我们要时刻清楚,复杂度分析只是一个理论模型,只能提供粗略的估计分析,我们不能直接根据复杂度判断算法的好坏,比如说算法1的时间复杂度是O(logn),算法2的时间复杂度是O(n),我们就不能直接断定算法1优于算法2,针对不同的环境,不同的数据集合,不同数据量的大小,在实际应用上可能真实的性能会不同
  • 大O复杂度表示法

大O时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以也叫做渐进时间复杂度,简称时间复杂度,同理可知大O空间复杂度的定义。

  • 时间复杂度分析要点
  1. 只关注循环执行次数最多的一段代码
  2. 加法法则:总复杂度等于量级最大的那段代码的复杂度
  3. 乘法法则:嵌套代码的复杂度等于嵌套内外的代码复杂度的乘积
  • 常见的复杂度量级
  1. 常量阶:O(1)
  2. 对数阶:O(logn)
  3. 线性阶:O(n)
  4. 线性对数阶:O(nlogn)
  5. 平方阶:O(n²)、立方阶:O(n³)、...... 、k次方阶:O()
  6. 指数阶:O()
  7. 阶乘阶:O(n!)
  • 复杂度分析常用的四种情况
  1. 最好情况时间复杂度
  2. 最坏情况时间复杂度
  3. 平均情况时间复杂度
  4. 均摊时间复杂度

复习<<数据结构与算法——数组>>

数组是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据,下面我们来看一下数组的特性。

  • 根据下标实现随机访问数组元素

我们知道计算机会给每个内存单元分配一个地址,计算机通过地址来访问内存中的数据。当计算机需要随机访问数组中的某个元素时,它会首先通过下面的寻址公式,计算出该元素存储的内存地址:

a[i]_address = base_address + i * data_type_size

有时候我们会有一种误解认为数组查找的时间复杂度为O(1),其实正确的说法应该是,数组支持随机访问,根据下标随机访问的时间复杂度为O(1)。

  • 低效的"插入"和"删除"操作
  1. 假设数组的长度为n,现在如果我们需要将一个数据插入到数组的第k个位置。为了把第k个位置腾出来给新来的数据,我们需要将第k~n这部分的元素都顺序地往后挪一位。但是当数组本身存储的数据并没有规律,只是当作一个存储数据的集合,在这种情况下,如果要将某个元素插入到第k个位置,为了避免大规模的数据搬移,我们可以直接将第k个数据转移到数组的尾后,再将插入元素存放在第k个位置,这样可以使得数组的插入操作时间复杂度始终保证为O(1),但是我们要知道,这种方法改变了数组当中其他元素的位置。
  2. 与插入数据类似,如果我们要删除数组当中的第k个位置的数据,为了保证内存的连续性,也需要搬移数据,不然数组当中就会出现空洞,内存也就不再连续了。在实际中的某些特殊场景下,我们并不一定非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,删除的效率会提高很多。比如我们需要依次删除数组中的第1、2、3个元素时,我们可以先记录下已经删除的数据。每次的删除操作并不是真正的搬移数据,只是记录数据已经被删除的位置。当数组没有更多空间存储数据时,我们再触发并执行一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。

总结可知,之所以数组具有低效的"插入"和"删除"特点,是由于数组本身要保持其自身的顺序性和连续性,当抛开这两点不谈时,数组低效的"插入"和"删除"的缺点也就无从谈起。

  • 大小固定

由于数组在创建的一开始需要指明其大小,这样才能够为其申请一块连续的存储空间,因此数组的大小是固定的。当数组内存储数据满后,就要涉及到数组扩容的操作,需要申请一块更大的空间,然后将原数据搬移到新的空间中,这样才能继续插入数据。

  • 数组下标越界问题

在C++中,通过下标访问不存在的元素是一种未定义行为,这会产生很严重的后果。所谓缓冲区溢出(buffer overflow)指的就是这类错误,这也是导致PC及其他设备上应用程序出现安全问题的一个重要原因。并且这类错误是编译器无法识别的,所以就需要我们程序员在编写代码时,注意确保数组的下标合法化。

复习<<数据结构与算法——链表>>

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成,下面我们来看一下链表的特性。

  • 支持纯天然的动态扩容

由于链表本身存储上非连续的特点,因此不需要为其申请指定的一块空间,当插入数据时候,只需动态的为新数据申请空间,然后通过指针将其与链表联系起来即可。

  • 高效的"插入"和"删除"操作

同样的由于链表本身存储上非连续的特点,使得链表对于指定位置结点的插入与删除操作变得十分高效,只需考虑操作位置结点的前后结点,以及操作结点本身这三个结点即可。无需进行大量的数据搬移以维持连续性。

  • O(n)时间复杂度的查找操作

由于链表本身并不是顺序存储在一段连续的空间,因此无法支持像数组那样高效的随机访问特性,当我们在链表当中按值查找某一个结点时,我们只能通过从头往后依次遍历每一个结点,然后判断是否为待查找结点这样的方式来进行数据的查找。

每天反复练习剑指offer上的五道题

字节跳动 Fighting Day1目标:

  • 剑指offer(一):二维数组中的查找
  • 剑指offer(六):旋转数组中最小数字
  • 剑指offer(十三):调整数组顺序使奇数位于偶数前面
  • 剑指offer(二十八):数组中出现次数超过一半的数字
  • 剑指offer(三十):连续子数组的最大和

一起加油跑腿的小徐

2019/5/14

Fighting——Day1相关推荐

  1. Alpha冲刺——day1

    Alpha冲刺--day1 作业链接 Alpha冲刺随笔集 github地址 站立式会议 会议安排:alpha冲刺的第一天,我们站立式会议讨论了我们接下来的安排,做出大致的规划,并针对之前的原型设计, ...

  2. python商业爬虫_商业爬虫学习笔记day1

    day1 一. HTTP 1.介绍: https://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html http://blog.csdn.ne ...

  3. 凯文·凯利:未来很美好,今天仍是Day1

    编者注:凯文·凯利(Kevin Kelly),常被称为"KK",<连线>(Wired Magazine)第一任主编:曾担任<全球评论>(Whole Eart ...

  4. WC2017 Day1

    WC2017 Day1 字符串算法 0x00 字符串的性质 字符串的周期(period):例如abcabca 周期为3 字符串的border :相同前后缀 显然如果一个长为s字符串有长度为r的bord ...

  5. noip2011提高组day1+day2解题报告

    Day1 T1铺地毯https://www.luogu.org/problem/show?pid=1003 [题目分析] 全部读入以后从最后一个往前找,找到一个矩形的范围覆盖了这个点,那这个矩形就是最 ...

  6. NOI Day1线上同步赛梦游记

    Preface 第一次体验NOI,虽然不是正式选手,但是打打同步赛还是挺涨姿势的,也算是体验了一把. Day1很爆炸,一方面是NOI题目的难度高于自身的水平,另一方面也出现了比较大的失误,T1一个数组 ...

  7. 培训补坑(day1:最短路two-sat)

    经过12天的滚粗,终于迎来了暑期培训的结尾啦QAQ 结业考才考了90分,真是对不起孙爷(孙爷请收下我的膝盖) orz小粉兔怒D rank 1 获得小粉兔一只QAQ 由于这次12天的培训题目又比较多,算 ...

  8. Java-GUI编程实战之管理系统 Day1【项目开发流程、软件三层架构、项目需求、项目结构分析】

    视频.课件.源码[链接:https://pan.baidu.com/s/13ffqGDzH-DZib6-MFViW3Q 提取码:zjxs] Java-GUI编程实战之管理系统 Day1[项目开发流程. ...

  9. HDU 4930 Fighting the Landlords(扯淡模拟题)

    Fighting the Landlords 大意: 斗地主....   分别给出两把手牌,肯定都合法.每张牌大小顺序是Y (i.e. colored Joker) > X (i.e. Blac ...

最新文章

  1. s:if 标签 字符串比较 正确用法和错误用法
  2. 宁夏大学计算机考研论坛,很多人认为宁夏大学考研题普通人都会做,不如一起来做下试试...
  3. Knative 基本功能深入剖析:Knative Serving 之服务路由管理
  4. Linux 从头学 01:CPU 是如何执行一条指令的?
  5. mysql 用户概念_传输概念 – db对象的用户/组/权限从mysql到postgresql
  6. CryptoJS -- JS加密算法库
  7. Python id(obj), ==, is 三者之间的区别
  8. Centos7安装Docker(二进制)
  9. Java实践(五)——类的声明与引用
  10. Eclipse中快速使代码对齐?1张图搞定!
  11. C#语法基础(三)----窗体设计
  12. JAVA_JDK下载与安装教程(小白)
  13. VMware卸载干净
  14. Linux命令 - df命令
  15. ramda 函数 String
  16. MT4外汇结余净值可用预付款
  17. 标注线段长度批量lisp_晓东CAD家园-论坛-每日插件-求批量多线段长度标注-求批量多线段长度标注插件!万分感谢!!! - Powered by Discuz!...
  18. 本题要求递归实现一个计算非负整数阶乘的简单函数。
  19. 微服务项目:尚融宝(38)(核心业务流程:申请借款额度(2))
  20. linux交互式进程初始化失败怎么办,电脑进入安全方式仍然显示交互式登录进程初始化失败...

热门文章

  1. 台式电脑c语言如何安装,体验篇—Type-C如何连接电脑_固态硬盘评测-中关村在线...
  2. 宝塔面板SSL证书显示不安全?这里我教你宝塔SSL证书如何配置及开启HTTPS访问的操作方法
  3. 【youcans 的 OpenCV 例程200篇】124. 孔洞填充的泛洪算法
  4. 【线性代数的本质是42】
  5. ros中启动rviz显示段错误,核心以转储问题 rviz process has died
  6. AE基础教程第一阶段——12轨道遮罩
  7. IE 阻止过期的 ActiveX 控件
  8. ZK框架的分析与应用
  9. zk-web框架的学习之路,重新认识Java,Eclipse安装zk插件
  10. 搭建FISCO BCOS联盟链节点