每日算法--1--复杂度

说在前面:本文是通过阅读作者魏梦舒的《漫画算法》所总结的笔记,仅供学习,如侵即删

 

1.什么是算法(alorithm)

数学领域里:算法是用于解决某一类问题的公式和思想

计算机领域里:它的本质是一系列程序指令,用于解决特定的运算和逻辑问题

 

2.算法有高效的,也有拙劣的

衡量算法好坏的重要标准有两个:时间复杂度和空间复杂度

算法的应用领域:(1)数学运算还不简单?,其实不然比如求两个数的最大公约数,要求做到效率的极致;求两个超大整数的和,不导致变量溢出,也要进行思考

(2)查找(3)排序(4)最优决策:求迷宫最佳路线等(5)面试(如果这条也算的话):考察你对计算机底层知识的了解or你的逻辑思维能力

 

3.什么是数据结构

data structure ,是算法的基石,是数据的组织,管理和存储格式,使用目的是为了高效地访问和修改数据

组成方式有哪些?

(1)线性结构

线性结构是最简单的结构,包括数组,链表,以及衍生出来的栈,队列,哈希表

(2)树

稍微有些复杂,有代表性的是二叉树

(3)图

更复杂的数据结构,呈现多对多的关联关系

(4)其他

各种由基本数据结构变形而来,用于解决某些特定问题

 

一,时间复杂度

1.算法的好与坏:

举个例:一个代码运行一次花100ms,占用内存5MB

               一个代码运行一次花100s,占用内存500MB

后者可以收拾东西走人了

衡量程序的好坏的重要因素:运行时间的长短和占用内存空间的大小

 

2.基本操作执行次数

(1)一个面包10cm,2分钟吃掉1cm,吃掉整个面包要多久?2*10即20分钟

        如果面包长度为ncm,所以为2*n

        用一个函数表达所需时间,可以记作T(n)=2n

(2)一个16cm的面包,5分钟吃掉面包剩余长度的一半,即第5分钟吃掉8cm,第10分钟吃掉4cm,第15分钟吃掉2cm,那么吃到只剩1cm,需要多久?

         这个问题化成数学问题即,16一直除以2,那么除几次结果等于1?涉及对数,即以2为底16的对数\log_{2}16

         所以到1cm即5*log16即20分钟

          用一个函数表达所需时间,可以记作T(n)=5logn

(3)一个长度为10cm的面包和一个鸡腿,每两分钟吃掉一个鸡腿,那么吃掉整个鸡腿需要多久?

       当然是2分钟,这里只要求吃鸡腿,和面包没有关系

       用一个函数表达所需时间,可以记作T(n)=2

(4)一个10cm的面包,吃第一个1cm花1分钟,吃第二个1cm花2分钟,每吃1cm所花时间就比上次多1分钟,即1累加到10的综合,也就是55分钟。

         如果面包长度为n呢?1+2+3+...+(n-1)+n

         用一个函数表达所需时间,可以记作T(n)=0.5n^2+0.5n

 

上面讲的是吃东西花费的时间,这个思想同样适用于对程序基本操作执行次数的统计

设T(n)为基本操作执行次数的函数(也可以认为是程序的相对执行时间函数),n为输入规模,

 

3.渐进时间复杂度:

若存在函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)时T(n)的同量级函数,记作T(n)=O(f(n)),称为O(f(n)),O为算法的渐进时间复杂度,简称为时间复杂度

直白的说,时间复杂度就是把程序的想对执行时间函数T(n)简化为一个数量级,这个数量级可以时n,n^2,n^3等

如何推导出时间复杂度呢?遵循一下几个原则:

(1)如果运行时间是常数量级,则用常数1表示

(2)只保留时间函数中的最高阶项

(3)如果最高阶项存在,则省去最高阶项前面的系数

例如:T(n)=3n,最高阶项为3n,省去系数3,则转化成T(n)=O(n)

           T(n)=5logn,最高阶项为5logn,省去系数5,则转化成T(n)=O(logn)

           T(n)=2,只有常数量级,则转化成T(n)=O(1)  

           T(n)=0.5n^2+0.5n,最高阶项为0.5n^2,省去系数0.5,则转化成T(n)=O(n^2)

 

所以当n足够大时谁用时更长,谁更节省时间呢?

O(1)<O(logn)<O(n)<O(n^2)

 

O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)冲突的话很麻烦的,指向的value会做二次hash到另外一快存储区域

 

二,空间复杂度

1.什么是空间复杂度:简单来说,空间复杂度就是执行算法的空间成本,是对一个算法在运行过程中临时占用存储空间大小的量度

举个例子:给n个整数,其中有两个是重复的,要求找出这两个重复的整数

31254872

一般最朴素的就是一个双重循环遍历,每遍历一个新的整数就回顾之前遍历过的所有整数,但是这个算法的时间复杂度太高O(n^2)

 

为了提高算法的效率,我们可以采用一个中间数据

比如每遍历一个整数,就把这个数存起来,放到字典里,不用再和之前的比对,只需要直接查找,看看是否有对应的整数即可

key

value
31
11
21
51
41
91
71

key代表整数的值,value代表出现的次数

当遍历到最后一个整数的时候很轻松就能找到2曾经出现过

keyvalue
31
11
22
51
41
91
71

因为读写字典的时间复杂度是O(1),所以整个算法的时间复杂度是O(n),比双重循环相比,运行效率增大了很多

但是内存空间是有限的,在时间复杂度相同的情况下,算法占用的内存空间当然是越小越好

所以程序占用空间大小的计算公式记作S(n)=O(f(n)),n为问题规模,f(n)为算法所占空间的函数

 

2.空间复杂度的计算

(1)常量空间:空间大小固定,和输入规模没有直接关系的时候,空间复杂度记为O(1)

(2)线性空间:当算法分配的空间是一个线性的集合(如数组),并且集合大小和输入规模n成正比,时间复杂度为O(n)

(3)二维空间:当算法分配的空间是一个二维数组的集合,并且集合长度和宽度都与输入规模n成正比,时间复杂度为O(n^2)

4)递归空间:是一个比较特殊的场景,虽然没有明显的声明变量或集合,但是计算机执行的时候,也会专门分出一块内存,用来存储“方法调用栈”,执行递归操作所需要的内存和空间和递归的深度是成正比的。纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是O(n)

 

3.时间与空间的取舍

在绝大多数时候,时间复杂度更为重要一些,我们宁可多分配一些内存空间也要提高程序的执行速度

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你白勺男孩TT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值