文章目录

  • 算法的时间复杂度和空间复杂度
    • 复杂度的分析
    • 一. 时间维度
      • 事后统计法
      • 事前分析估算的方法
      • 时间复杂度
        • (1)时间频度
        • (2)时间复杂度
          • 大O符号表示法
          • 常见的时间复杂度量级
            • 常数阶O(1)
          • 线性阶O(n)
          • 对数阶O(logN)
          • 线性对数阶O(nlogN)
          • 平方阶O(n^2^)
          • 立方阶O(n³)、K次方阶O(n^k)
    • 二、空间维度
      • 空间复杂度O(1)
      • 空间复杂度O(n)

算法的时间复杂度和空间复杂度

首先我们先了解什么是算法,算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。但是对于同一个问题,我们去使用不同的算法,结果或许会一样,但不同的地方就在于你所用算法所耗费的资源和时间,此篇博客就是用于去衡量不同算法的优劣。

复杂度的分析

衡量不同算法的优劣,主要还是根据算法所占的空间时间两个维度去考虑。但是,世界上不会存在完美的代码,既不消耗最多的时间,也不占用最多的空间,鱼和熊掌不可得兼,那么我们就需要从中去寻找一个平衡点,使得写出一份较为完美的代码。

一. 时间维度

是指执行当前算法所消耗的时间,我们通常用时间复杂度来描述。
算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。而度量一个程序的执行时间通常有两种方法

事后统计法

这种方法可行,但不是一个好的方法。该方法有两个缺陷:一是要想对设计的算法的运行性能进行评测,必须先依据算法编制相应的程序并实际运行;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素,有时容易掩盖算法本身的优势。

事前分析估算的方法

因事后统计方法更多的依赖于计算机的硬件、软件等环境因素,有时容易掩盖算法本身的优劣。因此人们常常采用事前分析估算的方法。
在编写程序前,依据统计方法对算法进行估算。一个程序在计算机上运行时所消耗的时间取决于下列因素:
(1) 算法采用的策略、方法;(2).编译产生的代码质量;(3) 问题的输入规模;(4)机器执行指令的速度。

时间复杂度

(1)时间频度

一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

(2)时间复杂度

在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

大O符号表示法

首先我们先看一个例子

for(i=1; i<=n; ++i)
{j = i;j++;
}

通过「 大O符号表示法 」,这段代码的时间复杂度为:O(n) ,为什么呢?

在 大O符号表示法中,时间复杂度的公式是: T(n) = O( f(n) ),其中f(n) 表示每行代码执行次数之和,而 O 表示正比例关系,这个公式的全称是:算法的渐进时间复杂度。

我们继续看上面的例子,假设每行代码的执行时间都是一样的,我们用 1颗粒时间 来表示,那么这个例子的第一行耗时是1个颗粒时间,第三行的执行时间是 n个颗粒时间,第四行的执行时间也是 n个颗粒时间(第二行和第五行是符号,暂时忽略),那么总时间就是 1颗粒时间 + n颗粒时间 + n颗粒时间 ,即 (1+2n)个颗粒时间,即: T(n) = (1+2n)*颗粒时间,从这个结果可以看出,这个算法的耗时是随着n的变化而变化,因此,我们可以简化的将这个算法的时间复杂度表示为:T(n) = O(n)

为什么可以这么去简化呢,因为大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。

所以上面的例子中,如果n无限大的时候,T(n) = time(1+2n)中的常量1就没有意义了,倍数2也意义不大。因此直接简化为T(n) = O(n) 就可以了。

常见的时间复杂度量级

常数阶O(1)
对数阶O(logN)
线性阶O(n)
线性对数阶O(nlogN)
平方阶O(n2)
立方阶O(n3)
K次方阶O(nk)
指数阶(2n)

上面从上至下依次的时间复杂度越来越大,执行的效率越来越低。

下面选取一些常见的进行讲解

常数阶O(1)

无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1),如:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

上述代码在执行的时候,它消耗的时候并不随着某个变量的增长而增长,那么无论这类代码有多长,即使有几万几十万行,都可以用O(1)来表示它的时间复杂度。

线性阶O(n)

这个在最开始的代码示例中就讲解过了,如:

for(i=1; i<=n; ++i)
{j = i;j++;
}

这段代码,for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。

对数阶O(logN)
int i = 1;
while(i<n)
{i = i * 2;
}

从上面代码可以看到,在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。我们试着求解一下,假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n
也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)

线性对数阶O(nlogN)

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。

就拿上面的代码加一点修改来举例:

for(m=1; m<n; m++)
{i = 1;while(i<n){i = i * 2;}
}
平方阶O(n2)

平方阶O(n²) 就更容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。
举例:

for(x=1; i<=n; x++)
{for(i=1; i<=n; i++){j = i;j++;}
}

这段代码其实就是嵌套了2层n循环,它的时间复杂度就是 O(n*n),即 O(n²)
如果将其中一层循环的n改成m,即:

for(x=1; i<=m; x++)
{for(i=1; i<=n; i++){j = i;j++;}
}

那它的时间复杂度就变成了 O(m*n)

立方阶O(n³)、K次方阶O(n^k)

参考上面的O(n²) 去理解就好了,O(n³)相当于三层n循环,其它的类似。

除此之外,其实还有 平均时间复杂度、均摊时间复杂度、最坏时间复杂度、最好时间复杂度 的分析方法,有点复杂,这里就不展开了。

二、空间维度

类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用 S(n) 来定义。

空间复杂度比较常用的有:O(1)、O(n)、O(n²),我们下面来看看:

空间复杂度O(1)

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)
举例:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)

空间复杂度O(n)

int[] m = new int[n]
for(i=1; i<=n; ++i)
{j = i;j++;
}

这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)

时间复杂度和空间复杂度(超详细)相关推荐

  1. 排序算法-算法时间复杂度和空间复杂度概念 详细讲解

    排序算法-算法时间复杂度和空间复杂度概念 详细讲解 排序算法的介绍 排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程. 排序的分类: 1)内部排序: 指将 ...

  2. 时间复杂度,空间复杂度(超详细)真香

    文章目录 算法的时间复杂度和空间复杂度 复杂度的分析 一. 时间维度 事后统计法 事前分析估算的方法 时间复杂度 (1)时间频度 (2)时间复杂度 大O符号表示法 常见的时间复杂度量级 常数阶O(1) ...

  3. 《数据结构》(一)时间复杂度和空间复杂度(超硬核八千字)

    ------------------时间复杂度和空间复杂度--------------------- 1.时间复杂度和空间复杂度 在学习数据结构和算法之前,每一个初学者第一步要熟练掌握的就是时间复杂度 ...

  4. 超强、超详细Redis数据库入门教程

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用r ...

  5. 超强、超详细Redis入门教程【转】

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用r ...

  6. 递归二分查找时间复杂度、空间复杂度和稳定性

    递归 递归条件 自己调用自己 有结束条件 二分查找 二分查找对1~100乱序数字查找 l = list(range(1,101)) def bin_search(data_set,val):low = ...

  7. 超详细的Java面试题总结(三)之Java集合篇常见问题

    系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 List,Set,Map三者的区别及总结 List:对付顺序的好帮手 Li ...

  8. 一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。并分析时间复杂度与空间复杂度。

    一串首尾相连的珠子(m个),有N种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短.并分析时间复杂度与空间复杂度. 这道题在网上著名的帖子 微软等公司数据结构+ ...

  9. 时间复杂度和空间复杂度简介

    算法复杂度分为时间复杂度和空间复杂度.其作用: 时间复杂度是指执行算法所需要的计算工作量: 空间复杂度是指执行这个算法所需要的内存空间. (算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算 ...

  10. 动态规划27k字超详细保姆级入门讲解——附DP经典线性、区间、二维图、四维8个模型题解

    动态规划27k字超详细保姆级入门讲解 写在前面: 这篇文章是目前为止我写过最长也是最久的文章,前面关于DP的讲解我查阅了大量的博客资料,学习其他博主对DP的理解,也翻阅了很多经典的纸质书籍,同时做了近 ...

最新文章

  1. pgsql中层次查询方法
  2. python怎么返回最初_Python 函数为什么会默认返回 None?
  3. 我的第三个jquery插件——promptForK13内容提示插件
  4. php 501解决办法,PHP 使用错误处理解析
  5. 我为啥不想用Python
  6. 自动劫持root密码
  7. use proxy for git
  8. “Windows Sandbox”——PC主系统从未如此安全
  9. 异常为当IDENTITY_INSERT设置为OFF时 解决办法
  10. java.lang.NoClassDefFoundError: com/baidu/ueditor/ActionEnter报错解决
  11. Android 源码结构简介
  12. ubuntu18.04 linux journalctl 命令
  13. Mac微信多开以及防撤回方案
  14. 回顾|Apache Flink Meetup · 北京站(附问题解答 PPT 下载)
  15. 国内十大白银期货APP最新排名
  16. excel 如何用公式函数去除单元格的空格和回车 并进行 单元格字符串比对
  17. VLA的AIPS简单绘图
  18. 如何设置html的背景效果,背景图片的透明度如何设置(CSS)
  19. 简介:cs224n 2022 winter [Chris Manning]
  20. js 获取浏览器高度和宽度值(兼容多浏览器)

热门文章

  1. fastlane二开java_iOS中使用Fastlane实现自动化打包和发布
  2. 微信小程序获取收货地址流程
  3. 【数字电子技术 Digital Electronic Technology 7】——时序逻辑电路分析 之 计数器完全攻略
  4. oracle dbms_utility.get_time,dbms_utility如何使用?
  5. 解决Edge及Chrome等浏览器主页被篡改2345导航页
  6. (五十七)方差分析与相关分析
  7. 阿里云个人网站备案流程
  8. Kafka 入门与实践
  9. TC118AH单通道内置MOS单通道直流无刷马达驱动IC
  10. 傅里叶变换之掐死教程(完整版)