算法基础--时间/空间复杂度

目录

  • 前言
  • 一、时间复杂度
    • 1.1 时间复杂度公式
    • 1.2 常见的时间复杂度量级
    • 1.3 时间复杂度量级示例
      • 1.3.1 常数阶O(1)
      • 1.3.2 对数阶O(logN)
      • 1.3.3 线性阶O(n)
      • 1.3.4 线性对数阶O(nlogN)
      • 1.3.5 平方阶O(n²)
      • 1.3.6 立方阶O(n³)、K次方阶O(n^k)
  • 二、空间复杂度
    • 2.1 O(1)
    • 2.2 O(n)
    • 2.3 O(n²)
  • 三、常用算法的时间复杂度
    • 3.1 O(1)相关算法
    • 3.2 O(logn)相关算法
    • 3.3 O(n)相关算法
    • 3.4 O(nlogn)相关算法
    • 3.5 O(n^ 2)相关算法


前言

算法是一组用于操作数据和解决问题的方法。尽管不同算法在解决同一问题时可能得到相同结果,但它们在资源消耗和执行时间上可能存在显著差异。
评估不同算法的优劣应主要考虑时间空间两个维度。

时间维度指算法执行所需的时间,通常用时间复杂度描述。
空间维度指算法执行所需的内存空间,通常用空间复杂度描述。

评估算法效率的关键在于其时间复杂度和空间复杂度。然而,有时时间和空间是一种取舍的关系,需要在二者之间取得平衡。

一、时间复杂度

评估算法的时间复杂度时,许多人可能首先考虑运行算法程序并测量其消耗的时间。尽管这种方法可行,但存在一些缺点。
这种方法容易受到运行环境的影响,在性能较高的计算机上运行的结果可能与在性能较低的计算机上运行的结果有很大差异。此外,测试数据规模对结果也有重要影响。另外,在编写算法时,可能无法完全运行算法。
因此,另一种更通用的方法是使用「大O符号表示法」,即 T(n) = O(f(n)),来描述算法的时间复杂度。

1.1 时间复杂度公式

时间复杂度的公式是: T(n) = O( f(n) )
有关此公式的解释如下:

  • 其中f(n) 表示每行代码执行次数之和,而 O 表示正比例关系,这个公式的全称是:算法的渐进时间复杂度。
  • 去简化:大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。

去简化示例:

for(i=1; i<=n; ++i)   //第1行
{                     //第2行    j = i;			  //第3行    j++;               //第4行    
}                     //第5行    

假设每行代码的执行时间都是一样的,用 1s来表示,那么

这个例子的第一行耗时是1s时间,
第三行的执行时间是 ns时间,
第四行的执行时间也是 ns时间(第二行和第五行是符号,暂时忽略),
那么总时间就是 1s时间 + ns时间 + ns时间 ,即 (1+2n)s个时间,即: T(n) = (1+2n)s 时间,
可以看出这个算法的耗时是随着n的变化而变化,因此如果n无限大的时候,T(n) = time(1+2n)中的常量1就没有意义了,倍数2也意义不大。因此直接简化为T(n) = O(n) 就可以了。

1.2 常见的时间复杂度量级

常数阶O(1)
对数阶O(logN)
线性阶O(n)
线性对数阶O(nlogN)
平方阶O(n²)
立方阶O(n³)
K次方阶O(n^k)
指数阶(2^n)

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

1.3 时间复杂度量级示例

1.3.1 常数阶O(1)

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

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

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

1.3.2 对数阶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)

1.3.3 线性阶O(n)

如:

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

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

1.3.4 线性对数阶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;}
}

1.3.5 平方阶O(n²)

平方阶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)

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

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


二、空间复杂度

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。
空间复杂度比较常用的有:O(1)、O(n)、O(n²)

2.1 O(1)

空间复杂度为O(1)的示例:

public void printNumber(int number) {System.out.println(number);
}

在这个示例中,无论输入的数字是多少,该函数只需要固定的空间来存储一个数字的内存空间,因此空间复杂度为O(1)。

2.2 O(n)

空间复杂度为O(n)的示例:

public void printNumbers(int[] numbers) {for (int i = 0; i < numbers.length; i++) {System.out.println(numbers[i]);}
}

在这个示例中,函数接收一个整型数组作为参数,然后遍历整个数组并打印每个元素。随着输入数组大小的增加,需要存储的元素数量也相应增加,因此空间复杂度为O(n)。

2.3 O(n²)

空间复杂度为O(n²)的示例:

public void printMatrix(int[][] matrix) {for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println();}
}

在这个示例中,函数接收一个二维整型数组作为参数,然后遍历整个二维数组并打印每个元素。由于有两层嵌套循环,随着输入二维数组的大小增加,需要存储的元素数量将呈二次方增长,因此空间复杂度为O(n²)

三、常用算法的时间复杂度

3.1 O(1)相关算法

O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

3.2 O(logn)相关算法

比如O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。

3.3 O(n)相关算法

时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法。

3.4 O(nlogn)相关算法

O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。

3.5 O(n^ 2)相关算法

再比如时间复杂度O(n^ 2),就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。

参考链接:
算法的时间与空间复杂度(一看就懂)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/808029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

API管理平台:你用的到底是哪个?

Apifox是不开源的&#xff0c;在github的项目只是readme文件&#xff0c;私有化需要付费。当然saas版目前是免费使用的。 一、Swagger 为了让Swagger界面更加美观&#xff0c;有一些项目可以帮助你实现这一目标。以下是一些流行的项目&#xff0c;它们提供了增强的UI和额外的功…

Qt 容器类整理与使用

Qt提供了哪些容器类 Qt 提供了丰富的容器类&#xff0c;这些容器类主要用于存储和管理数据&#xff0c;按照其内部组织结构和功能特性&#xff0c;大致可分为顺序容器和关联容器两大类&#xff1a;顺序容器&#xff1a; QList - 动态数组&#xff0c;支持快速的头部和尾部插入…

OSCP靶场-- Sybaris

OSCP靶场–Sybaris 考点(redis MODULE LOAD命令执行) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.158.93 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-11 04:24 EDT Nmap scan report for 192.168.158.93…

照片转漫画的软件有吗?分享4款热门的软件!

在数字化时代&#xff0c;我们总是追求新鲜、有趣、创意十足的方式来展现自我。其中&#xff0c;将普通照片转化为漫画风格的图像已成为许多年轻人的新宠。这种既能保留原照片中的人物特征&#xff0c;又能赋予其独特艺术气息的方式&#xff0c;让许多人趋之若鹜。那么&#xf…

PHP7垃圾回收算法

前提 本文为了梳理PHP GC工作流程&#xff0c;所以从引用计数、部分标记清除算法做引子&#xff0c;然后介绍PHP GC工作流程,最后介绍性能更高的GC算法 引用计数 概述 引用计数算法中引入了一个概念计数器。计数器代表对象被引用的次数 基本原理 为了记录一个对象有没有被…

APB协议中的PSEL、PSTROB、PENABLE、PREADY这4个信号的作用与用法

在详细探讨APB&#xff08;Advanced Peripheral Bus&#xff09;协议中的这四个信号之前&#xff0c;让我们先简单了解一下APB协议。APB是ARM公司的一种简单但高效的总线协议&#xff0c;主要用于低带宽和低性能需求的外围设备连接&#xff0c;如定时器、接口控制、UART等。它是…

微信公众号第三方平台-公众号扫码授权接入代运营

文章目录 接入目的效果展示技术积累如何成为服务商如何搭建第三方后端服务传统模式V云服务模式如何完成商家授权授权逻辑介绍 环境准备注册开发者平台-个人类型 传统模式后端代码接收公众号个人三方平台的票据根据票据获取三方平台访问令牌根据访问令牌获取预授权码通过预授权码…

OJ 【难度1】【Python】完美字符串 扫雷 A-B数对 赛前准备 【C】精密计时

完美字符串 题目描述 你可能见过下面这一句英文&#xff1a; "The quick brown fox jumps over the lazy dog." 短短的一句话就包含了所有 2626 个英文字母&#xff01;因此这句话广泛地用于字体效果的展示。更短的还有&#xff1a; "The five boxing wizards…

[Linux] 权限控制命令 chmod、chown和chgrp

文章目录 chmodchownchgrp chmod 在Linux系统中&#xff0c;root用户可以使用chmod命令来修改文件的权限&#xff0c;并且root用户也可以授权普通用户来执行chmod命令。要将权限授予普通用户修改一个文件的权限&#xff0c;可以使用以下步骤&#xff1a; 使用root用户登录到L…

网络——初识网络

在现如今&#xff0c;网络已经成了一种基础设施&#xff0c;大到国家&#xff0c;小到个人&#xff0c;网络已经充斥在我们每个人的身 边&#xff0c;如果一个人突然失去了网络&#xff0c;那么它的生活或多或少会出现一些不方便的地方&#xff0c;网络现在已 经伴随着我们的吃…

axios-mock-adapter使用

文章目录 1. 安装 axios-mock-adapter2. 引入所需的库3. 创建一个模拟适配器实例4. 定义模拟响应5. 在你的代码中使用 axios6. 在测试或开发完成后清理模拟 axios-mock-adapter 是一个用于模拟 axios HTTP 请求的库。它允许你在测试或开发过程中&#xff0c;为 axios 实例提供…

Solana主网使用自定义的RPC进行转账

1、引言 如果用 browser 连接主网的 RPC server 会收到 error code 403 message 為 Access forbidden, contact your app developer or supportrpcpool.com. 错误&#xff0c;因为主网的 RPC server 会检查 HTTP Header 如果判断出來是 browser 就会报告 403 錯誤。 要解決这…

【LeetCode热题100】53. 最大子数组和(数组)

一.题目要求 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 二.题目难度 中等 三.输入样例 示例 1&#xff1a; 输入&#xff1a;nu…

N 皇后 - 蓝桥杯?-Lua 中文代码解题第6题

n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回 n 皇后问题 不同的解决方案的数量。 示例 1&#xff1a; 输入&#xff1a;n 4 输出&#xff1a;2 解释&#xff1a;如上图所示&…

吴恩达2022机器学习专项课程(一) 5.2 向量化(1) 5.3 向量化(2)

问题预览/关键词 什么是向量化&#xff1f;向量化的好处是&#xff1f;如何向量化多元线性回归函数的参数&#xff1f;如何在Python中向量化参数&#xff1f;计算机底层是如何计算向量化的&#xff1f;向量化示例 笔记 1.向量化 一种在数学和计算中广泛使用的概念&#xff…

[Mac]安装App后“XX已损坏,无法打开“

问题&#xff1a; “xx.app”已损坏&#xff0c;无法打开。你应该将它移到废纸篓。 解决&#xff1a; 终端输入sudo xattr -r -d com.apple.quarantine 后将Applications中对应的问题app拖入生成路径&#xff0c;然后执行。 $ sudo xattr -r -d com.apple.quarantine /Appli…

备战蓝桥杯(日益更新)(刷题)

备战蓝桥杯&#xff08;日益更新&#xff09;&#xff08;刷题&#xff09; 文章目录 备战蓝桥杯&#xff08;日益更新&#xff09;&#xff08;刷题&#xff09;前言&#xff1a;一、二分&#xff1a;1. acwing503 借教室&#xff1a;&#xff08;二分 差分&#xff09;2. ac…

使用列表递推实现螺旋矩阵

下面是使用列表递推实现螺旋矩阵的代码&#xff1a; def generate_spiral_matrix(n):# 创建一个大小为n*n的矩阵&#xff0c;初始值为0matrix [[0] * n for _ in range(n)]# 定义上下左右四个边界top, bottom, left, right 0, n - 1, 0, n - 1# 定义当前要填充的数字num 1w…

Socks5代理IP如何使用?详细教程解析

当我们在互联网上浏览网页、下载文件或者进行在线活动时&#xff0c;隐私和安全问题常常被提及。在这样的环境下&#xff0c;一个有效的解决方案是使用Sock5IP。本教程将向您介绍Sock5IP的使用方法&#xff0c;帮助您保护个人隐私并提升网络安全。 一、什么是Sock5IP&#xff1…

上线后菜单卡片未显示

上线后菜单卡片未显示 背景 需要开发儿童模式&#xff0c;对菜单、通知等页面根据年龄段进行隐藏。为了兼容二期需求&#xff0c;这次的开发划分了三个年龄段&#xff1a;14岁以下&#xff0c;14~17岁&#xff0c;18岁以上。 实现方式 涉及的表添加一个可见度字段&#xff…