时间空间复杂度入门

简介: 本文介绍时间与空间复杂度入门知识,使用Big O表示法(如O(1)、O(n)、O(n²)),强调估算而非精确计算,保留最高次项。时间复杂度常由循环嵌套层数决定,空间复杂度看额外内存占用。分析以最坏情况为主,越小越好。结合多个代码示例,帮助初学者理解复杂度分析的基本方法与常见误区。

时间空间复杂度入门
对于初学者,你只需要记住以下几点:
1、时空复杂度用 Big O 表示法表示(类似O(1), O(n²), O(logn) 等)。它们都是估计值,不需要精确计算,且仅保留最高增长项。
比方说 O(2n²+3n+1)等同于 O(n²)O(n²),O(1000n+1000) 等同于 O(n)O(n)。
2、我们分析算法的复杂度时,一般分析的是最坏情况的复杂度。它们都是越小越好。比方说时间复杂度 O(n)的算法比 O(n²)的算法执行效率高,空间复杂度 O(1)的算法比 O(n)的算法内存消耗小。
当然,一般我们要说明这个 n 代表什么,比如 n 代表输入的数组的长度。
4、如何估算?现在你可以简单理解:时间复杂度大部分情况下就是看 for 循环的最大嵌套层数;空间复杂度就看算法申请了多少空间来存储数据。
注意
以上的分析方法中,有些细节并不严谨:
1、按照 for 循环的嵌套层数来估算时间复杂度是简化的方法,其实不完全准确。
2、大部分时候我们是分析最坏情况下的复杂度,但是对于数据结构 API 的复杂度衡量,我们会分析平均复杂度。
举几个例子来说比较直观。
时间/空间复杂度案例分析
示例一,时间复杂度 O(n),空间复杂度 O(1):
算法包含一个 for 循环遍历 nums 数组,所以时间复杂度是 O(n),其中 n 代表 nums 数组的长度。我们的算法只使用了一个 sum 变量,这个 nums 是题目给的输入,不算在我们算法的空间复杂度里面,所以空间复杂度是 O(1)。
示例二,时间复杂度 O(n),空间复杂度 O(1):
其实只有当 n 是 10 的倍数时,算法才会执行 for 循环,时间复杂度是 O(n)。其他情况下算法会直接返回,时间复杂度是 O(1)。但是算法复杂度只考察最坏情况,所以这个算法的时间复杂度是 O(n),空间复杂度是 O(1)。
示例三,时间复杂度 O(n²),空间复杂度 O(1):
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
// 数组是否存在两个数,它们的和为 target?
boolean hasTargetSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return true;
}
}
}
return false;
}
算法包含两个 for 循环嵌套,所以时间复杂度是 O(n²),其中 n 代表 nums 数组的长度。
我们的算法只使用了 i, j 两个变量,这是常数级别的空间消耗,所以空间复杂度是 O(1)。
你也许会说,内层的 for 循环并没有遍历整个数组,且有可能提前 return,算法实际执行的次数应该是小于 n²的,时间复杂度还是 O(n²)吗?
是的,还是 O(n²)。前面说了 Big O 表示法是估计值,不需要精确计算。具体到不同的输入,算法的实际执行次数确实会小于 n²,但我们不需要关心。
简单说就是:看到嵌套 for 循环,时间复杂度就是 O(n²)。
示例四,时间复杂度 O(n),空间复杂度 O(n):
Java
运行代码
复制代码
1
2
3
void exampleFn(int n) {
int[] nums = new int[n];
}
这个函数中创建了一个大小为 n 的数组,所以空间复杂度是 O(n)。
申请数组空间及初始化数组也需要时间,所以时间复杂度也是 O(n)。
时间复杂度并不仅仅体现在你看得到的 for 循环,每一行代码都可能有隐藏的时间复杂度。所以说要了解常见数据结构的实现原理,这是准确分析时间复杂度的基础。
示例五,时间复杂度 O(n),空间复杂度 O(n):
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
// 输入一个整数数组,返回一个新的数组,新数组的每个元素是原数组对应元素的平方
int[] squareArray(int[] nums) {
int[] res = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
res[i] = nums[i] * nums[i];
}
return res;
}
算法初始化 res 数组需要 O(n)的时间复杂度,包含一个 for 循环,时间复杂度也是 O(n),总的时间复杂度是还是 O(n)其中 n 代表 nums 数组的长度。
我们声明了一个新的数组 res,这个数组的长度和 nums 数组一样,所以空间复杂度是 O(n)。

相关文章
|
3月前
|
Java Maven 数据安全/隐私保护
Nexus仓库
Nexus是一款开源仓库管理工具,支持Maven、NPM、Docker等格式。本文介绍其在Linux与Docker环境下的安装配置,包括JDK部署、OSS版下载、仓库创建、用户权限管理及密码重置方法,并涵盖私服搭建、持久化存储、资源上传与匿名访问设置,助力企业高效构建私有仓库体系。
|
Python Windows
win64系统安装32位的python解释器和打包成exe程序
本文说明了在win64系统环境下,如何安装32位的python解释器,同时对32位虚拟环境下运行的python程序进行打包,将其打包成可执行的exe程序,以图文相结合的方式记录了操作步骤,供大家参考。
1156 0
|
Cloud Native Dubbo 应用服务中间件
阿里巴巴捐献的14个顶级开源项目,国内开源贡献第一!
代表性的项目包括龙蜥操作系统、Apache RocketMQ、Apache Dubbo、Spring Cloud Alibaba 等
|
前端开发 Java 关系型数据库
【Mybatis-Plus】mybatisplus更新时,实体字段为空,数据库不更新的解决方案
【Mybatis-Plus】mybatisplus更新时,实体字段为空,数据库不更新的解决方案
1411 0
|
算法 安全 搜索推荐
TLS 协议-对称加密原理
TLS 协议-对称加密原理
804 0
|
3月前
|
存储 Ubuntu Shell
容器命令
介绍Docker容器常用命令,涵盖创建、启动、端口映射、日志查看、文件拷贝及数据卷挂载等操作,详解交互式与守护式容器运行模式、exec与attach区别、commit提交镜像、容器继承数据卷等核心知识点,助力掌握容器生命周期管理。
|
3月前
|
关系型数据库 MySQL 数据库
-Docker安装Mysql
本教程介绍Docker安装MySQL 5.7的完整流程,涵盖单机部署与主从复制配置。包括解决中文乱码、数据持久化卷映射,以及主从同步设置,确保数据安全与高可用,适用于生产环境部署参考。
|
3月前
|
存储 数据采集 监控
RFID助力钢材应用智能化管理
RFID技术通过在钢材上绑定耐高温抗金属标签,实现生产、仓储、出库全流程数据化管理,自动采集信息,提升追溯精度与库存准确率至99.5%以上,减少60%人工操作,助力钢铁企业智能化升级。
|
3月前
|
监控 负载均衡 网络协议
健康检测:这个节点都挂了,为啥还要疯狂发请求?
本文探讨RPC框架中服务健康检测的挑战与优化。通过真实案例揭示:当节点网络异常、心跳间歇失败时,仅依赖心跳机制易导致“半死不活”节点持续接收请求。提出结合业务请求可用率(成功次数/总调用次数)动态评估节点状态,弥补传统心跳机制的不足,实现更精准的健康判断,提升系统稳定性与可用性。
|
3月前
|
负载均衡 安全 数据库
异常重试:在约定时间内安全可靠地重试
本节讲解RPC框架中的异常重试机制,重点探讨如何在超时控制、节点避让和异常判定的基础上实现安全可靠的重试。需确保业务逻辑幂等,设置重试白名单,并在每次重试前重置超时时间,避免耗时超标,提升系统容错性与稳定性。(239字)

热门文章

最新文章