算法的时间与空间复杂度

算法是指用来操作数据、解决程序问题的一种方法。对于同一问题,使用不同的算法,也许最终结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。

那我们该如何去衡量不同算法之间的优劣呢?主要还是从算法所占用的【时间】和【空间】两个维度去考量。

  • 时间维度:是指执行当前算法所消耗的时间,我们通常用【时间复杂度】来描述;
  • 空间维度:是指执行当前算法所需要占用多少内存空间,我们通常用【空间复杂度】来描述。

因此,评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。然而,有的时候时间和空间却又是鱼和熊掌不可兼得,那我们就需要从从中去取一个平衡点。

下面我来分别介绍一下【时间复杂度】和【空间复杂度】的计算方式。

一、时间复杂度

我们想要知道一个算法的【时间复杂度】,很多人首先想到的方法就是把这个算法程序运行一遍,那么它所消耗的时间就自然而然知道了。

这种方式可以吗?当然可以,不过它有很多弊端。

这种方式很容易受运行环境影响,在性能高的机器上跑出来的结果与性能低的机器上跑出来的结果相差会很大。而且对测试时使用的数据规模也有很大关系。再者,我们在写算法的时候,还没有办法完整的去运行呢。

因此,另一种更为通用的方法就出来了:【大O符号表示法】,即T(n)=O(f(n))。

我们先来看个例子:

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个颗粒时间(第二行和第五行是符号,暂时忽略),那么总时间就是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(n^{2})
  • 立方阶O(n^{3})
  • k次方阶O(n^{k}n^{k})
  • 指数阶O(2^{n})

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

下面选取一些较为常用的来讲解游戏啊(没有严格按照顺序):

1. 常数阶O(1)

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

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

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

2. 线性阶O(n)

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

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

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

3. 对数阶O(logN)

还是先来看代码:

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

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

4. 线性对数阶O(nlogN)

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

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

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

5. 平方阶O(n^{2})

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

举例:

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

    }
}

这段代码其实就是嵌套了两层n循环,它的时间复杂度就是O(n*n),即O(n^{2})

如果将其中一层循环的n改成m,即:

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

    }
}

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

6. 立方阶O(n^{3})、k次方阶O(n^{k})

参考上面的O(n^{2})去理解就好了,O(n^{3})相当云三层n循环,其它的类似。

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

二、空间复杂度

既然时间复杂度不是用来计算程序具体耗时的,那么我也应该明白,空间复杂度也不是用来计算程序实际所占用的空间的。

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

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

1. 空间复杂度O(1)

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

举例:

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

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

2. 空间复杂度O(n)

我们先看一个代码:

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

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

以上,就是对算法的时间复杂度和空间复杂度基础的分析,欢迎大家一起交流。

算法的时间与空间复杂度(一看就懂)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最新!2023年台湾10米DEM地形瓦片数据

上次更新谷歌倾斜摄影转换生成OSGB瓦片V1.1版本&#xff0c;使用该版本生产了台北、台中、桃园三个地方的倾斜摄影OSGB数据&#xff0c;在OSGB可视化软件中进行展示&#xff0c;可视化效果和加载效率俱佳。已经很久没更新地形瓦片数据&#xff0c;主要是热点地区的原始数据没有…

6.S081的Lab学习——Lab5: xv6 lazy page allocation

文章目录 前言一、Eliminate allocation from sbrk() (easy)解析&#xff1a; 二、Lazy allocation (moderate)解析&#xff1a; 三、Lazytests and Usertests (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0…

HTTP Digest Access Authentication Schema

HTTP Digest Access Authentication Schema 背景介绍ChallengeResponse摘要计算流程总结参考 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 HTTP Digest Access Authentication Schema&#xff…

STL库--stack

目录 stack的定义 stack容器内元素的访问 stack常用函数实例解析 stack的常见用途 stack的定义 其定义的写法和其他STL容器相同&#xff0c;typename可以任意基本类型或容器&#xff1a; stack<typename> name; stack容器内元素的访问 由于栈本身就是一种后进先出…

Java Class类简介

一、类图&#xff1a; 二、基本介绍&#xff1a; 1. Class也是类&#xff0c;因此也继承了Object类。 2. Class类的对象不是new出来的&#xff0c;是系统创建的。 类加载器ClassLoader有个方法LoadClass()&#xff0c;将某个类对应的Class对象生成在堆中。 通过调试可以发现&am…

代码随想录-Day23

669. 修剪二叉搜索树 方法一&#xff1a;递归 class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if (root null) {return null;}if (root.val < low) {return trimBST(root.right, low, high);} else if (root.val > high) {return trimBS…

python基础-数据结构-leetcode刷题必看-queue---队列-python的底层构建

文章目录 队列双端队列 deque底层存储deque接口1. __init__(self, iterable: Iterable[_T], maxlen: int | None None) -> None2. append(self, __x: _T) -> None3. appendleft(self, __x: _T) -> None4. copy(self) -> Self5. count(self, __x: _T) -> int6. …

GoFly框架快速新增接口/上手写代码

拿到一个新框架大家可能无从下手&#xff0c;因为你对框架设计思路、结构不了解&#xff0c;从而产生恐惧&#xff0c;所以我们框架是通过简单可视化界面安装&#xff0c;安装后即可看到效果&#xff0c;然后点击先点点看各个功能&#xff0c;看现有的功能是怎么写的&#xff0…

怎样清理Mac存储空间 苹果电脑内存不够用怎么办 苹果电脑内存满了怎么清理

在使用 Mac 电脑的过程中&#xff0c;用户经常会遇到磁盘空间不足的困扰&#xff0c;这时候就需要寻找有效的方法来清理苹果电脑内存了。 清理Mac存储空间可以通过多种方法进行&#xff0c;以确保你的Mac能够高效运行并释放宝贵的存储空间。以下是一些有效的清理和优化方法&am…

swift 自定义扫码功能

使用功能​​​​​​​ 1. 调用扫码功能&#xff08;扫描二维码/条形码、图片识别二维码/条形码、生成二维码/条形码&#xff09; 2. 自定义扫码界面UI&#xff08;继承式自定义修改样式&#xff0c;完全自定义调用封装组件&#xff09; 3. 生成二维码/条形码 源码地址&#x…

Parquet使用指南:一个超越CSV、提升数据处理效率的存储格式

前言 在大数据时代&#xff0c;数据存储和处理的效率越来越重要。同时&#xff0c;我们在工作中处理的数据也越来越多&#xff0c;从excel格式到csv格式&#xff0c;从文件文档传输到直接从数据库提取&#xff0c;数据单位也从K到M再到G。 当数据量达到了G以上&#xff0c;几…

串口通信问题排查总结

串口通信问题排查 排查原则&#xff1a; 软件从发送处理到接收处理&#xff0c;核查驱动、控制及发送接收数据是否正常。硬件从发送到接收&#xff0c;针对信号经过的各段&#xff0c;分段核对信号是否正常。示波器、逻辑分析仪。用万用表、示波器、逻辑分析仪等工具&#xf…

Hadoop3:MapReduce之简介、WordCount案例源码阅读、简单功能开发

一、概念 MapReduce是一个 分布式运算程序 的编程框架&#xff0c;是用户开发“基于 Hadoop的数据分析 应用”的核心框架。 MapReduce核心功能是将 用户编写的业务逻辑代码 和 自带默认组件 整合成一个完整的 分布式运算程序 &#xff0c;并发运行在一个 Hadoop集群上。 1、M…

【高频】redis快的原因

相关问题&#xff1a; 1.为什么Redis能够如此快速地进行数据存储和检索&#xff1f; 2.Redis作为内存数据库,其内存存储有什么优势吗? 3.Redis的网络模型有何特点,如何帮助提升性能? 一、问题回答 Redis使用了内存数据结构&#xff0c;例如字符串、哈希表、列表、集合、有…

pycharm中,出现SyntaxError: Non-ASCII character ‘\xe4‘ in file... 的问题以及解决方法

文章目录 一、问题描述二、解决方法 一、问题描述 在pycharm中&#xff0c;使用python中编写中文字符时&#xff0c;会提示如下错误信息&#xff1a; SyntaxError: Non-ASCII character \xe4 in file ...... on line 8, but no encoding declared; see http://python.org/dev…

TypeScript-初识

TypeScript 是具有类型语法的JavaScript&#xff0c;是一门强类型的编程语言 变量不能做随意类型赋值 好处&#xff1a; 1️⃣ 静态类型检查&#xff0c;提前发现代码错误 function arrToStr(arr: Array<string>){return arr.join() } arrToStr(123) // 类型“stri…

网页版应用授权的核心难点

Web应用的出现 随着数字化时代发展&#xff0c;越来越多的企业开始关注工业软件上云。这种趋势不仅满足了企业对于提高生产效率、降低运维成本的需求&#xff0c;还帮助企业更好地应对市场竞争、实现产业升级和智能制造。 在软件上云的过程中&#xff0c;会产生新产品形态和新…

2024 京麟ctf -MazeCodeV1

文章目录 检查代码思路一个字节的指令注意附上S1uM4i佬们的exp https://www.ctfiot.com/184181.html 检查 代码 __int64 __fastcall check_solve(char *a1) {__int64 result; // rax__int64 v2; // rax__int64 index_step; // rax__int64 v4; // rax__int64 v5; // rax__int64…

贪心(临项交换)+01背包,蓝桥云课 搬砖

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 0搬砖 - 蓝桥云课 (lanqiao.cn) 二、解题报告 1、思路分析 将物品按照w[i] v[i]升序排序然后跑01背包就是答案 下面证明&#xff1a;&#xff08;不要问怎么想到的&#xff0c;做题多了就能想到&#xff…

一致性hash算法原理图和负载均衡原理-urlhash与least_conn案例

一. 一致性hash算法原理图 4台服务器计算hash值图解 减少一台服务3台服务器计算hash值图解 增加一台服务器5台服务器计算hash值图解 二. 负载均衡原理-urlhash与least_conn 2.1.urlhash案例 # urlhash upstream tomcats {hash $requ