一篇文章搞懂时间复杂度和空间复杂度

不知道小伙伴们有没有刷过力扣上的算法题,我在上研究生的时候,刷过了前40道题,上面的算法题,我觉得还挺难的,当你写完代码的时候,就可以提交自己写的代码到系统上,系统会给你写的代码计算时间复杂度和空间复杂度,并给出了你的排名。可能有的小伙伴不理解这个概念,今天我们来详细讲一下。

在编写和优化代码时,时间复杂度和空间复杂度是两个关键概念。它们帮助我们衡量算法的效率和资源使用情况,从而选择最优的解决方案。本文将详细探讨这两个概念,并通过具体的例子来说明它们在实际编程中的应用。

时间复杂度?

时间复杂度描述了一个算法的运行时间如何随着输入数据规模的增长而变化。它通常用大O符号表示,例如O(1)、O(n)、O(log n)等。以下是几种常见的时间复杂度类型及其含义:

O(1) - 常数时间复杂度
不管输入数据的大小如何,算法的执行时间始终相同。常数时间复杂度表示算法的运行时间不受输入数据规模的影响。

例子:

public int GetFirstElement(int[] array)
{return array[0];
}

解释:
这段代码总是返回数组的第一个元素,不管数组有多大,花费的时间都是一样的。这就像从一堆书里拿起最上面的一本书,不管书堆有多高,拿起一本书的时间始终不变。

示例图:

   函数调用:                    数组:GetFirstElement(array)        [10, 20, 30, 40, 50]|                       0   1   2   3   4|                           ↑返回 array[0]                ||O(1)  <--------------------+注释:访问数组第一个元素的操作始终是常数时间,不受数组大小影响。

通过这种方式,我们可以清晰地展示O(1)时间复杂度的概念,即无论输入数据的大小如何,算法的执行时间始终相同。

O(n) - 线性时间复杂度
算法的执行时间与输入数据规模成正比。当输入数据增大时,运行时间也线性增长。

**例子:**求数组每个元素之和

public int Sum(int[] array)
{int sum = 0;foreach (int item in array){sum += item;}return sum;
}

解释:
这个函数需要遍历整个数组来计算所有元素的总和。数组越大,需要的时间就越长。就像你需要逐个数数一堆硬币,硬币越多,数完的时间就越长。

示例图

scss复制代码函数调用:                       数组:
Sum(array)                       [10, 20, 30, 40, 50]|                           0   1   2   3   4|                           ↑   ↑   ↑   ↑   ↑
遍历每个元素  <------------------  ||
时间复杂度:O(n)  <---------------+注释:计算数组所有元素的总和需要遍历整个数组,运行时间与数组大小成正比。

O(log n) - 对数时间复杂度
算法的执行时间随着输入数据规模的增长按对数比例增加。这通常出现在需要将数据集分成较小部分的算法中,例如二分查找。

**例子:**在有序数组中查找目标元素的索引

public int BinarySearch(int[] array, int target)
{int left = 0;int right = array.Length - 1;while (left <= right){int mid = left + (right - left) / 2;if (array[mid] == target)return mid;if (array[mid] < target)left = mid + 1;elseright = mid - 1;}return -1;
}

解释:
这个函数使用二分查找法来寻找目标元素。每次迭代都会把搜索范围缩小一半。这就像在一本按字母顺序排列的字典里查一个词,每次翻开中间的页面,决定目标词在前半部分还是后半部分,然后重复这个过程。

示例图

scss复制代码函数调用:                       数组:
BinarySearch(array, target)     [10, 20, 30, 40, 50]|                          0   1   2   3   4|                         第一次比较:|                         mid = 2 -> 30 == target ?|                         目标小于30,搜索范围缩小一半|                         新范围: [10, 20]|                                  0   1|                         第二次比较:|                         mid = 0 -> 10 == target ?|                         目标大于10,搜索范围缩小一半|                         新范围: [20]|                                  1|                         第三次比较:|                         mid = 1 -> 20 == target ?|                         找到目标,返回索引1↑||O(log n) <----------------+注释:每次迭代搜索范围缩小一半,因此执行时间按对数比例增加。

O(n^2) - 平方时间复杂度
算法的执行时间与输入数据规模的平方成正比。这通常出现在嵌套循环中,每个循环遍历输入数据。

**例子:**将数组中的数据从小到大排序

public void BubbleSort(int[] array)
{for (int i = 0; i < array.Length - 1; i++){for (int j = 0; j < array.Length - i - 1; j++){if (array[j] > array[j + 1]){int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}
}

解释:
这个函数使用冒泡排序算法对数组进行排序。它包含两个嵌套的循环,每个循环都会遍历数组。就像你要给一堆学生排座次,每次都要两两比较,整个过程需要很多次。

示例图

less复制代码函数调用:                        数组:
BubbleSort(array)                 [30, 10, 40, 20, 50]外层循环 i = 0:|                          第一次比较:30 > 10, 交换|                          新数组:[10, 30, 40, 20, 50]内层循环 j = 0:|                          第二次比较:30 > 40, 不交换|                          新数组:[10, 30, 40, 20, 50]|                          第三次比较:40 > 20, 交换|                          新数组:[10, 30, 20, 40, 50]|                          第四次比较:40 > 50, 不交换外层循环 i = 1:|                          第一次比较:10 > 30, 不交换|                          新数组:[10, 30, 20, 40, 50]内层循环 j = 1:|                          第二次比较:30 > 20, 交换|                          新数组:[10, 20, 30, 40, 50]|                          第三次比较:30 > 40, 不交换... (持续进行直到排序完成)↑||O(n^2) <---------------------+注释:每次外层循环遍历数组,内层循环也遍历数组,因此执行时间与数组大小的平方成正比。

O(2^n) - 指数时间复杂度
算法的执行时间随着输入数据规模的增长按指数比例增加。这种复杂度通常出现在递归算法中,尤其是解决组合问题时。

例子:

public int Fibonacci(int n)
{if (n <= 1)return n;return Fibonacci(n - 1) + Fibonacci(n - 2);
}

解释:
这个函数计算斐波那契数列的第n个数字。每次调用函数时,它会递归调用自身两次,导致总的调用次数按指数增长。

示例图

scss复制代码Fibonacci(5)|-------------|             |
Fib(4)        Fib(3)|             |
----         -----
|   |       |     |
Fib(3) Fib(2) Fib(2) Fib(1)|     |     |       |
---   ---   ---     ---
| |   | |   | |     |
Fib Fib Fib Fib Fib Fib
(2) (1) (1) (0) (1) (0)|...注释:每次调用函数时,它会递归调用自身两次,导致总的调用次数按指数增长,时间复杂度为 O(2^n)。
空间复杂度?

空间复杂度描述了一个算法在运行时需要的内存空间如何随着输入数据规模的增长而变化。以下是几种常见的空间复杂度类型及其含义:

O(1) - 常数空间复杂度
算法所需的内存空间不随输入数据规模的变化而变化。

例子:

public int GetFirstElement(int[] array)
{return array[0];
}

解释:
这个函数只返回数组的第一个元素,不需要额外的内存空间。就像你只拿一张桌子放书,无论书堆多高,只用一张桌子就够了。

示例图

scss复制代码函数调用:                      数组:
GetFirstElement(array)          [10, 20, 30, 40, 50]|                          0   1   2   3   4|                            ↑
返回 array[0]                        ||O(1)  <---------------------+注释:访问数组第一个元素的操作不需要额外的内存空间,内存使用量不随输入数据规模变化。

O(n) - 线性空间复杂度
算法所需的内存空间与输入数据规模成正比。

例子:

public int[] CopyArray(int[] array)
{int[] newArray = new int[array.Length];for (int i = 0; i < array.Length; i++){newArray[i] = array[i];}
}

解释:
这个函数创建了一个和输入数组一样大的新数组。就像你需要一个新的箱子来装一堆硬币,硬币越多,箱子就得越大。

示例图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

O(n^2) - 平方空间复杂度
算法所需的内存空间与输入数据规模的平方成正比。

例子:

public int[,] CreateMatrix(int n)
{int[,] matrix = new int[n, n];return matrix;
}

解释:
这个函数创建了一个n x n的矩阵。随着n的增加,所需的内存空间按平方增长。

示例图

scss复制代码函数调用:                        矩阵:
CreateMatrix(n)                   n = 2|                          [1, 1]|                          [1, 1]|                          矩阵大小:2 x 2||                          n = 3|                          [1, 1, 1]|                          [1, 1, 1]|                          [1, 1, 1]|                          矩阵大小:3 x 3||                          n = 4|                          [1, 1, 1, 1]|                          [1, 1, 1, 1]|                          [1, 1, 1, 1]|                          [1, 1, 1, 1]|                          矩阵大小:4 x 4↑||O(n^2)  <---------------------+注释:创建一个n x n的矩阵所需的内存空间随着n的平方增长。

O(2^n) - 指数空间复杂度
算法所需的内存空间随着输入数据规模的增长按指数比例增加。

**例子:**字符串的所有子集

public List<string> GenerateSubsets(string str)
{if (str.Length == 0){return new List<string> { "" };}char first = str[0];List<string> subsets = GenerateSubsets(str.Substring(1));List<string> newSubsets = new List<string>();foreach (string subset in subsets){newSubsets.Add(first + subset);newSubsets.Add(subset);}return newSubsets;
}

解释:
这个函数生成字符串的所有子集。随着字符串长度的增加,生成的子集数量按指数增长,需要的内存空间也按指数增长。

示例图

scss复制代码函数调用:
GenerateSubsets("abc")|---------------|             |
GenSub("bc")  GenSub("bc")|             |
GenSub("c")   GenSub("c")|             |
GenSub("")    GenSub("")|             |[""]           [""]生成的子集:["", "c", "b", "bc", "a", "ac", "ab", "abc"]空间复杂度:O(2^n)

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

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

相关文章

页面速度是如何影响SEO的?

搜索引擎使用复杂的算法来衡量您网站的重要方面&#xff0c;以决定是否向您发送流量。 搜索引擎使用您网站的小元素来确定您网站的质量和真实性&#xff0c;然后此操作将转化为您的网页在搜索引擎结果页面 中出现的位置。提高您在 SERP 中的排名的过程称为搜索引擎优化 (SEO)。…

【c】如何利用C语言控制可用性(用户是否可以修改值)

引入: 大家有没有想过设计一个函数控制功能的使用权限或变量修改权限? 我们首先来看代码: #include<stdio.h> bool usability==false;//初始值设为false是为了检查第一次设置有没有设置成功void setUsability(bool choice){usability=choice; } void printUsabilit…

JavaScript学习笔记(六)

37、JavaScript 错误 - Throw 和 Try to Catch try 语句使您能够测试代码块中的错误。 catch 语句允许您处理错误。 throw 语句允许您创建自定义错误。 finally 使您能够执行代码&#xff0c;在 try 和 catch 之后&#xff0c;无论结果如何。 37.1 JavaScript try 和 catc…

第57期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

Datawhale - 角色要素提取竞赛

文章目录 赛题要求一、赛事背景二、赛事任务三、评审规则1.平台说明2.数据说明3.评估指标4.评测及排行 四、作品提交要求五、 运行BaselineStep1&#xff1a;下载相关库Step2&#xff1a;配置导入Step3&#xff1a;模型测试Step4&#xff1a;数据读取Step5&#xff1a;Prompt设…

Yi-1.5 9B Chat 上线Amazon SageMaker JumpStart

你是否对简单的API调用大模型感到不满足&#xff1f;是否因为无法亲自部署属于自己的大模型而烦恼&#xff1f; 好消息来了&#xff0c;Amazon SageMaker JumpStart 初体验 CloudLab实验上线啦&#xff01; 本实验将以零一万物最新发布的中文基础模型 Yi-1.5 9B Chat 为例&am…

kettle从入门到精通 第七十四课 ETL之kettle kettle调用https接口教程,忽略SSL校验

场景&#xff1a;kettle调用https接口&#xff0c;跳过校验SSL。&#xff08;有些公司内部系统之间的https的接口是没有SSL校验这一说&#xff0c;无需使用用证书的&#xff09; 解决方案&#xff1a;自定义插件或者自定义jar包通过javascript调用https接口。 1、http post 步…

ArcGIS Pro SDK (七)编辑 9 使用草图

ArcGIS Pro SDK &#xff08;七&#xff09;编辑 9 使用草图 文章目录 ArcGIS Pro SDK &#xff08;七&#xff09;编辑 9 使用草图1 切换草图选择模式2 聆听草图修改事件3 收听草图完成前事件并修改草图4 收听草图完成事件5 触发草图事件的自定义构造工具6 自定义自定义草图工…

Pytorch添加自定义算子之(10)-mmdeploy编译流程

整体参考 一、mmcv的编译安装 见上一篇 opencv的安装 $env:OpenCV_DIR = "D:\git_clone\opencv\build" # 我这里下载解压之后的地址 $env:path = "$env:OpenCV_DIR\x64\vc15\bin;" + $env:path $env:path = "D:\git_clone\opencv\build\OpenCVConf…

后仿真中《SDF反标必懂连载篇》之 多个SDF 文件反标疑问

设计经过综合之后会生成门级网表,在门级网表里面包含了时序信息,这时的验证称之为后仿,除了验证功能是否满足,还要验证时序是否有违例的情况。 门级网表又分为,pr前和pr后,后端做完布局布线之后的,修改好timing的网表称为带时序的pr网表,pr网表进行仿真时,后端布局布…

嵌入式UI开发-lvgl+wsl2+vscode系列:8、控件(Widgets)(一)

一、前言 这里将介绍一系列控件&#xff0c;了解后就可以开始基础的开发了。 二、示例 1、Base Obj&#xff08;基础对象&#xff09; 1.1、示例1 #include "../../lv_examples.h" #if LV_BUILD_EXAMPLESvoid lv_example_obj_1(void) {lv_obj_t * obj1;obj1 lv…

Python容器 之 列表--列表的常用操作方法

1.查询相关方法&#xff1a;index()、count() &#xff08;1&#xff09;index() 说明&#xff1a; 和 字符串中的 find() 的作用是一样 列表中是没有 find() 方法的, 只有 index() 方法&#xff1b;字符串中 同时存在 find() 和 index() 方法 格式&#xff1a;列表.index(要查…

Linux时间子系统8:clock_event_device

1、前言 上一篇我们谈到了timer&#xff0c;在详细分析hrtimer的实现之前&#xff0c;我们先追根溯源来谈一下clockevent。先抛开clockevent这个概念&#xff0c;如果硬件要支持定时功能&#xff0c;那么硬件必然要能够支持产生定时时间&#xff0c;通过异步中断的方式通知CPU&…

计算机科学中的接口(Interface)介绍

计算机科学中的接口&#xff08;Interface&#xff09;介绍 计算机科学中&#xff0c;接口是一个广泛的概念&#xff0c;在不同上下文中有不同含义&#xff1a; 1.任何两电路或设备间的连接电路&#xff0c;用于连接CPU与内存、CPU与外设之间。这是一个重要的硬件层面的接口概…

你必须要知道的自闭症知识,推荐收藏

自闭症&#xff0c;一种日益受到关注的神经发育障碍&#xff0c;对于许多人来说&#xff0c;仍充满了神秘和误解。以下是 12 个你必须知道的关于自闭症的重要知识点&#xff1a; 1、自闭症并非心理问题 自闭症是一种生理上的神经发育障碍&#xff0c;不是由于孩…

Linux: security: openssh: ssh 登陆变慢又一例;strace的使用

文章目录 问题分析解决问题 今天遇到一个问题,ssh登陆服务器比平时慢了20秒。 分析 这种问题的分析,首先要靠strace,trace sshd的服务进程,看看有没有卡在某个系统调用上。 确实抓到了慢的原因;这里sshd向169.254.195.0:1812 发送了一个消息,然后接下来使用select,等…

亚马逊TM商标跟卖,同行截流采集,人工手动跟卖选品更方便!

区分TM标&#xff0c;软件自动查询&#xff0c;人工手动查询方便。 大家好&#xff0c;跟大家说下如何区分TM标。 选择相对于的站点&#xff0c;选择TM。 软件采集出来的已备案、未备案TMR标&#xff0c;现在点击TM标就会跳到美国商标局。 可以清晰的看到这个地方只有一个序…

张颂文百花提名,男配界笑出“颂”彩

在这个星光熠熠的百花奖舞台上&#xff0c; 张颂文老师犹如一坛陈年老酒&#xff0c;越品越有味&#xff0c; 竟不声不响地提名了最佳男配角&#xff01;这下可好&#xff0c; 男配界仿佛一夜之间被“颂”风吹得花枝乱颤&#xff0c;笑料百出。你说张颂文老师这演技&#xf…

DreamTech联合南大和牛津发布最强3D内容生成大模型——Direct3D

文章链接&#xff1a;https://arxiv.org/pdf/2405.14832 github链接&#xff1a;https://nju-3dv.github.io/projects/Direct3D/ 从文本和图像生成高质量的3D资产一直是一项挑战&#xff0c;主要是由于缺乏能够捕捉复杂几何分布的可扩展3D表示。在这项工作中&#xff0c;介绍…

详解反向传播(BP)算法

文章目录 what&#xff08;是什么&#xff09;where&#xff08;用在哪&#xff09;How&#xff08;原理&&怎么用&#xff09;原理以及推导过程pytorch中的反向传播 what&#xff08;是什么&#xff09; 反向传播算法&#xff08;Backpropagation&#xff09;是一种用于…