1.时间复杂度分析O(f(n))

分析方法

  • 只关注循环执行次数最多的一段代码
  • 加法原则
  • 乘法原则
  • 高优先级原则

常见时间复杂度量级

多项式量级和非多项式量级。其中,非多项式量级只有两个:O(2^n) 和 O(n!)。

我们把时间复杂度为非多项式量级的算法问题叫作 NP(Non-Deterministic Polynomial,非确定多项式)问题。

当数据规模 n 越来越大时,非多项式量级算法的执行时间会急剧增加,求解问题的执行时间会无限增长。

2.O(1)

O(1) 只是常量级时间复杂度的一种表示方法,并不是指只执行了一行代码


int i = 8;
int j = 6;
int sum = i + j;

一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)

3.O(logn)、O(nlogn)

对数阶时间复杂度非常常见,同时也是最难分析的一种时间复杂度.


i=1;
while (i <= n) {
i = i * 2;
}

不管是以 2 为底、以 3 为底,还是以 10 为底,我们可以把所有对数阶的时间复杂度都记为 O(logn)。

对数之间是可以互相转换的,log3n 就等于 log32 * log2n,所以 O(log3n) = O(C * log2n),其中 C=log32 是一个常量。基于我们前面的一个理论:在采用大 O 标记复杂度的时候,可以忽略系数,即 O(Cf(n)) = O(f(n))。所以,O(log2n) 就等于 O(log3n)

因此,在对数阶时间复杂度的表示方法里,我们忽略对数的“底”,统一表示为 O(logn)

4.O(m+n)、O(m*n)


int cal(int m, int n) {
int sum_1 = 0;
int i = 1;
for (; i < m; ++i) {
sum_1 = sum_1 + i;
} int sum_2 = 0;
int j = 1;
for (; j < n; ++j) {
sum_2 = sum_2 + j;
} return sum_1 + sum_2;
}

m 和 n 是表示两个数据规模。我们无法事先评估 m 和 n 谁的量级大,所以我们在表示复杂度的时候,就不能简单地利用加法法则,省略掉其中一个。上面代码的时间复杂度就是 O(m+n)。

针对这种情况,原来的加法法则就不正确了,我们需要将加法规则改为:T1(m) + T2(n) = O(f(m) + g(n))。但是乘法法则继续有效:T1(m)*T2(n) = O(f(m) * f(n))

5.空间复杂度分析

时间复杂度的全称是渐进时间复杂度,表示算法的执行时间与数据规模之间的增长关系。类比一下,空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系。


void print(int n) {
int i = 0;
int[] a = new int[n];
for (i; i <n; ++i) {
a[i] = i * i;
} for (i = n-1; i >= 0; --i) {
print out a[i]
}
}

第 2 行代码中,我们申请了一个空间存储变量 i,但是它是常量阶的,跟数据规模 n 没有关系,所以我们可以忽略。第 3 行申请了一个大小为 n 的 int 类型数组,除此之外,剩下的代码都没有占用更多的空间,所以整段代码的空间复杂度就是 O(n)。

常见的空间复杂度就是 O(1)、O(n)、O(n2),像 O(logn)、O(nlogn) 这样的对数阶复杂度平时都用不到。

6.四个复杂度概念

最好情况时间复杂度(best case time complexity)、最坏情况时间复杂度(worst case time complexity)、平均情况时间复杂度(average case time complexity)、均摊时间复杂度(amortized time complexity)

最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度

最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度

最好情况时间复杂度和最坏情况时间复杂度对应的都是极端情况下的代码复杂度,发生的概率其实并不大。为了更好地表示平均情况下的复杂度,我们需要引入另一个概念:平均情况时间复杂度,简称为平均时间复杂度

要查找的变量 x 在数组中的位置,有 n+1 种情况:在数组的 0~n-1 位置中和不在数组中。我们把每种情况下,将各种情况发生的概率考虑进去,查找需要遍历的元素个数累加起来,然后再除以 n+1,就可以得到需要遍历的元素个数的平均值,即:

不考虑概率



考虑概率

在大多数情况下,我们并不需要区分最好、最坏、平均情况时间复杂度三种情况。只有同一块代码在不同的情况下,时间复杂度有量级的差距,我们才会使用这三种复杂度表示法来区分。

均摊时间复杂度,平均复杂度只在某些特殊情况下才会用到,而均摊时间复杂度应用的场景比它更加特殊、更加有限。

【algo&ds】1.时间复杂度和空间复杂度分析的更多相关文章

  1. 【algo&ds】2.线性表

    1.线性表 线性表(英语:Linear List)是由n(n≥0)个数据元素(结点)a[0],a[1],a[2]-,a[n-1]组成的有限序列. 其中: 数据元素的个数n定义为表的长度 = " ...

  2. 【algo&ds】4.B树、字典树、红黑树、跳表

    上一节内容[algo&ds]4.树和二叉树.完全二叉树.满二叉树.二叉查找树.平衡二叉树.堆.哈夫曼树.散列表 7.B树 B树的应用可以参考另外一篇文章 8.字典树Trie Trie 树,也叫 ...

  3. C#中常用的排序算法的时间复杂度和空间复杂度

    常用的排序算法的时间复杂度和空间复杂度   常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 ...

  4. [Java初探外篇]__关于时间复杂度与空间复杂度

    前言 我们在前面的排序算法的学习中了解到了,排序算法的分类,效率的比较所使用到的判断标准,就包括时间复杂度和空间复杂度,当时因为这两个定义还是比较难以理解的,所以决定单独开一篇文章,记录一下学习的过程 ...

  5. 算法时间复杂度、空间复杂度(大O表示法)

    什么是算法? 计算机是人的大脑的延伸,它的存在主要是为了帮助我们解决问题. 而算法在计算机领域中就是为了解决问题而指定的一系列简单的指令集合.不同的算法需要不同的资源,例如:执行时间或消耗内存. 如果 ...

  6. php算法基础----时间复杂度和空间复杂度

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

  7. Python语言算法的时间复杂度和空间复杂度

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

  8. 从js 讲解时间复杂度和空间复杂度

    1. 博客背景 今天有同事在检查代码的时候,由于函数写的性能不是很好,被打回去重构了,细思极恐,今天和大家分享一篇用js讲解的时间复杂度和空间复杂度的博客 2. 复杂度的表示方式 之前有看过的,你可能 ...

  9. 【algo&ds】【吐血整理】4.树和二叉树、完全二叉树、满二叉树、二叉查找树、平衡二叉树、堆、哈夫曼树、B树、字典树、红黑树、跳表、散列表

    本博客内容耗时4天整理,如果需要转载,请注明出处,谢谢. 1.树 1.1树的定义 在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结 ...

随机推荐

  1. 基于Prometheus和Grafana的监控平台 - 环境搭建

    相关概念 微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics. Logging - 用于记录离散的事件.例如,应用程序的调试信息或错误信息.它是我们诊断问题的依据. ...

  2. 为什么要实现 IDisposable 接口?

    一.背景 最近在精读 <CLR Via C#>和 <Effective C#> 的时候,发现的一个问题点.一般来说,我们实现 IDisposable 接口,是为了释放托管资源和 ...

  3. 正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)

    1.引言 说道“心跳”这个词大家都不陌生,当然不是指男女之间的心跳,而是和长连接相关的.顾名思义就是证明是否还活着的依据. 什么场景下需要心跳呢?目前我们接触到的大多是一些基于长连接的应用需要心跳来“ ...

  4. 利用 js 的一些函数调用,排序

    编辑器:Sublime Text 3 1.冒泡排序 let arr = new Array(5,9,3,6,7,8,4,2,);bubbleSort(arr);console.log(arr);fun ...

  5. [USACO10NOV]奶牛的图片Cow Photographs

    题目描述 Farmer John希望给他的N(1<=N<=100,000)只奶牛拍照片,这样他就可以向他的朋友炫耀他的奶牛. 这N只奶牛被标号为1..N. 在照相的那一天,奶牛们排成了一排 ...

  6. python属性的默认值

    python类的构造函数中属性可以设置默认值,实例化出来的对象如果属性使用默认值,默认值的地址是相同的. class A: def __init__(self, name = []): self.__ ...

  7. SpringBoot之ConfigurationProperties 源码解读

    前言 ConfigurationProperties 是SpringBoot引入的一个和外部配置文件相关的注解类.它可以帮助我们更好的使用外置的配置文件属性. 源码解析 属性注入到Java类 @Tar ...

  8. .NET中国开发者峰会11.9 下午分会场1 内容解析

    China .NET Conf 2019中国 .NET 开发者峰会即将在上海召开,这次大会是一届完全由社区组织举办的中国.NET 开发者盛会,我们筹备大会之初就定下了大会的主题是“开源.共享.创新”. ...

  9. nginx 前后端分离 代理转发,解决跨域问题

    场景 适用于公司有前端,项目采用前后端分离.类似于我们 后端 springboot 提供接口,前端专门写html调用相应的接口,解决跨域问题 配置说明 worker_processes 1; even ...

  10. vue 代码迁移的坑

    由于开发需要,开发过程中总会遇到由于代码调试.svn/git上传等过程中,总会出现代码迁移文件的需求,很多时候,迁移过后总会出现一些大大小小的问题, 首先,需要迁移文件内有没有系统自动隐藏的文件(例如 ...