算法核心——空间复杂度和时间复杂度超详细解析

算法核心——空间复杂度和时间复杂度超详细解析

一、什么是算法

算法

  • 一个有限指令集
  • 接受一些输入(有些情况下不需要收入)
  • 产生输出
  • 一定在有限步骤之后终止
  • 每一条指令必须:
  1. 有充分明确的目标,不可以有歧义
  2. 计算机能处理的范围之内
  3. 描述应不依赖于任何一种计算机语言以及具体的实现手段

其实说白了,算法就是一个计算过程解决问题的方法。我们现在已经知道数据结构表示数据是怎么存储的,而“程序=数据结构+算法”,数据结构是静态的,算法是动态的,它们加起来就是程序

对算法来说有输入,有输出,相当于函数参数返回值。我们写算法的时候习惯把算法封装到一个函数中。

二、什么是好的算法

好,从上面我们知道了什么是算法,下面我再说什么是好的算法
在解决同一个问题的时候,我们通常会有很多种不一样的算法,区别就在于,有的算法比较笨,有的算法比较聪明,那我们怎么去衡量它们谁好谁坏呢?我们通常有下面两个指标:

  • 空间复杂度:根据算法写成的程序在执行时占用存储单元的长度。
  • 时间复杂度:根据算法写成的程序在执行时耗费时间的长度。

先举个例子说,如果让你打印十个整数,你那个程序可能瞬间就给出结果了,如果让你打印十万个整数呢?这你就得多等一会了。所以这个程序运行的时间,就跟你要处理的数据是十个还是十万个是相关的,这个十万就是我们要处理的数据的规模。我们把它叫做n,是一个变量的话,那我们这个程序所用的时间空间都跟这个n是有直接关系的。解决一个问题有很多中不同的方法,你在设计这个方法的时候,一定要把这两个要素考虑清楚。一不小心,如果空间复杂度太大的话,你那个程序就可能直接爆掉了,非正常中断,我一会会在后面讲,时间复杂度如果太大的话,你就可能等很长时间都等不出结果。

时间复杂度


先来看上面图片中的几组代码,我是用Python表示的,你在看的时候考虑两个问题:

  1. 四组代码中,哪组的运行时间最短?
  2. 用什么方式来体现算法运行的快慢?

刚才说n可以看作数据的规模,规模不一样,运行时间肯定也不一样,而且所用时间也不好确定,不同的n会得到不同的时间,所以我们用时间复杂度来表示算法运行的快慢。
先来看下面图片中的几个生活中的事件,估计时间:


这里你会发现我们会用“”表示一个大概,后面还有相应的时间单位,那时间复杂度也参照类似的方法:
时间复杂度:用来评估算法运行效率的一个式子

看上面图片所示,先说print(‘Hello World’),它的时间复杂度表示为O(1),O严格来说,它表示数学上一个式子的上界,我们可以简单的理解为就是一个估计,大约,相当于上面说的“”。1可以理解为是个运行单位(类似于秒这样的单位),为什么是O(1),因为print(‘Hello World’)只执行了一次,同理分析第二个:

for i in range(n):    print(‘Hello World‘)

它的时间复杂度表示为O(n),因为这组代码执行了n次。n还是个单位,同理,分析第三个:

for i in range(n):    for j in range(n):        print(‘Hello World‘)

它的时间复杂度表示为O(),因为是有两层循环,所以是,还是个单位。第四个你自己就可以分析了,我就不多此一举了。但千万不要以为就是这么简单,咱再看下面代码图片:

看到这个图片,你是不是感觉很良好,和你猜的差不多是吧,哈哈,不要高兴的太早,告诉你们,错了,它们的时间复杂度不是这样的。
为什么?我说了,“1”是单位,但“3”不是单位,3是3乘1,就比如说在生活中,问你一壶水烧多长时间,没有人回答说是三个几分钟或者几个三分钟。再说第二个,是单位,n也是个单位,但是比n大,所以我们在估计时用大单位,就好比生活中问你大概睡了多久,你一般说是几个小时,而不是说几个小时零几分钟,你强调的是一个大概的时间,明白了吧。
所以正确的时间复杂度是这样的:


第一个为什么是O(1),首先print(‘Hello World‘)打印一次和打印三次实际的影响不大吧,就是不管执行几次,只要它的规模不上升到n这么大的时候,换句话说,1是个单位,所以不管怎样,因为这是表示近似,不是表示精确的,所以是O(1).好,再看下面这个图片:

当你的循环减半的时候,时间复杂度就会变为O(logn)。所以你可以这样记,当算法过程出现循环折半的时候,复杂度式子中会出现logn。

时间复杂度小结

  • 时间复杂度是用来估计算法运行时间的一个式子(单位)
  • 一般来说,时间复杂度高的算法比时间复杂度低的算法慢
常见的时间复杂度(按效率排序)



复杂问题的时间复杂度

如何简单快速地判断算法复杂度

空间复杂度


在空间复杂度中需要注意的一点就是理解“空间换时间”,在研究一个算法的时候,时间比空间重要。

此篇完

原文地址:https://www.cnblogs.com/zyx110/p/11852975.html

时间: 2024-08-28 07:52:26

算法核心——空间复杂度和时间复杂度超详细解析的相关文章

JFinal 源码超详细解析之DB+ActiveRecord

我记得以前有人跟我说,"面试的时候要看spring的源码,要看ioc.aop的源码"那为什么要看这些开源框架的源码呢,其实很多人都是"应急式"的去读,就像读一篇文章一下,用最快的速度把文章从头到尾读一遍,那结果就是当你读完它,你也不清楚它讲了一个什么故事,想表达什么. 一个优秀的架构的源码我认为就好像一本名著一样,你的"文学"水平越高,你就越能读出作者设计的精妙之处.一篇源码在你不同水平的时候,能读出不同的东西,因此,我觉得优秀的框架的源码是经久

算法面试课程笔记000 玩转算法面试 leetcode题库分门别类详细解析

算法面试课程笔记 =============================================================================== 本文地址 : =============================================================================== liuyubobobo老师 <<玩转算法面试 leetcode题库分门别类详细解析>> 为了面试,更为了提升你的算法思维 http:/

【智能算法】粒子群算法(Particle Swarm Optimization)超详细解析+入门代码实例讲解

喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 算法起源 粒子群优化算法(PSO)是一种进化计算技术(evolutionary computation),1995 年由Eberhart 博士和kennedy 博士提出,源于对鸟群捕食的行为研究 .该算法最初是受到飞鸟集群活动的规律性启发,进而利用群体智能建立的一个简化模型.粒子群算法在对动物集群活动行为观察基础上,利用群体中的个体对信息的共享使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得最优解.

【优化算法】Greedy Randomized Adaptive Search算法 超详细解析,附代码实现TSP问题求解

01 概述 Greedy Randomized Adaptive Search,贪婪随机自适应搜索(GRAS),是组合优化问题中的多起点元启发式算法,在算法的每次迭代中,主要由两个阶段组成:构造(construction)和局部搜索( local search). 构造(construction)阶段主要用于生成一个可行解,而后该初始可行解会被放进局部搜索进行邻域搜索,直到找到一个局部最优解为止. 02 整体框架 如上面所说,其实整一个算法的框架相对于其他算法来说还算比较简单明了,大家可以先看以

jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

代理模式是一种很常见的模式,关于底层原理网上看到很多的有关的讲解,但看了一些都觉得比较粗略,很多时候把底层代码copy下来也不大讲解,感觉不如自己详细的写上一篇.本文将以非常详细的说明来分析jdk动态代理底层的实现原理,篇幅较长,但是每个核心方法代码中每步都有说明.还请耐心阅读 1.举例 public class ProxyFactory implements InvocationHandler { private Class target; public <T>T getProxy(Clas

Dubbo应用启动与停止脚本,超详细解析

本周刚好研究了一下dubbo的启动脚本,所以在官网的启动脚本和公司内部的启动脚本做了一个整理,弄了一份比较通过的Dubbo应用启动和停止脚本.          下面的脚本只应用于配置分离的应用,什么叫做配置分离呢?就是使用maven打包时,借助assemble插件,打一个tar.gz的压缩包.里面有三个目录.bin目录,用来存放启动与停止的脚本,lib目录,用来存放相关依赖的jar包,注意,这里每个jar包都是单独的,而不是一个大的jar包.conf目录,用来存放配置文件,包括dubbo.pr

转:算法的空间复杂度

转自:算法的空间复杂度 类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数.渐近空间复杂度也常常简称为空间复杂度. 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度.一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面. 我们在写代码时,完全可以用空间来换取

JAXB常用注解讲解(超详细)

简介: JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档.从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数. 一个简单的例子: Person.class : @XmlRo

算法和空间复杂度:转发:https://mp.weixin.qq.com/s/z_0D4u56cFvki2Q7IhzQlQ

常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!) 一般情况下,对一个问题(或一类算法)只需选择一种基本操作来讨论算法的时间复杂度即可,有时也需要同时考虑几种基本操作,甚至可以对不同的操作赋予不同的权值,以反映执行不同操作所需的相对时间,这种做法便于综合比较解决同一问题的两种完全不同的算法. 求解算法的时间复杂度的具体步骤 找出算法中的基本语句: 算法中执行次数最多