算法的复杂度解析(时间复杂度和空间复杂度)

2023-11-14

1.算法的复杂度:

算法的时间复杂度和空间复杂度合称为算法的复杂度。

时间复杂度: 时间复杂度是指执行算法所需要的计算工作量;

空间复杂度: 是对一个算法在运行过程中临时占用存储空间大小的量度;

算法的复杂性体运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度。

2.时间复杂度:

一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度,记为T(n)。

一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f (n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
在这里插入图片描述

1.大O表示法:

用O( )来体现算法时间复杂度的记法,我们称之为大O表示法。

算法复杂度可以从最理想情况、平均情况和最坏情况三个角度来评估,由于平均情况大多和最坏情况持平,而且评估最坏情况也可以避免后顾之忧,因此一般情况下,我们设计算法时都要直接估算最坏情况的复杂度。大O表示法所表示的是一个算法在最糟糕情况下的运行时间。

2.大O推导方法:

1.用常数1来取代运行时间中所有加法常数。

2.修改后的运行次数函数中,只保留最高阶项

3.最高项除去其相乘的常数,得到的结果就是大O阶。

举例:

单个循环体情况:

void Demo(int n){
		for(int j = 0; j < n; j++) {        // 循环次数为 n
            printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
        }
}
//时间复杂度为 O(n × 1),即 O(n)。

多重循环体情况:

void Demo(int n) {
for(int i = 0; i < n; i++) {            // 循环次数为 n
        for(int j = 0; j < n; j++) {        // 循环次数为 n
            printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
        }
    }
}   
//时间复杂度为 O(n × n × 1),即 O(n^2)。

多个事件复杂度情况:

void Demo(int n) {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            printf("Hello, World!\n");// 第一部分时间复杂度为 O(n^2)
        }
    }
    for(int j = 0; j < n; j++) {
        printf("Hello, World!\n");// 第二部分时间复杂度为 O(n)
    }
}
//时间复杂度为 max(O(n^2),O(n)),即 O(n^2)。

3.一些常见的大O运行时间:

  • O(log n),对数时间,二分查找。
  • O(n),线性时间,简单查找。
  • O(n logn),快速排序——速度较快的排序算法。
  • O(n²),选择排序——速度较慢的排序算法。
  • O(n!),旅行商问题的解决方案——非常慢的算法。

3.空间复杂度:

一个程序的空间复杂度是指运行完一个程序所需内存的大小,利用程序的空间复杂度,可以对程序的运行所需要的内存多少有个预先估计。一个程序执行时除了需要存储空间和存储本身所使用的指令、常数、变量和输入数据外,还需要一些对数据进行操作的工作单元和存储一些为现实计算所需信息的辅助空间。程序执行时所需存储空间包括以下两部分。

(1)固定部分:这部分空间的大小与输入/输出的数据的个数多少、数值无关,主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间,这部分属于静态空间。

(2)可变空间:这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等,这部分的空间大小与算法有关。一个算法所需的存储空间用f(n)表示。S(n)=O(f(n)),其中n为问题的规模,S(n)表示空间复杂度。

通常来说,只要算法不涉及到动态分配的空间以及递归、栈所需的空间,空间复杂度通常为0(1)。

4.个别特殊举例:

1.斐波那契数列的时间和空间复杂度

//递归情况下的斐波那契数列
    public static int Fib(int num){
        if (num==1||num==2){
            return num;
        }
        return Fib(num-2)+Fib(num-1);
    }

递归的时间复杂度是: 递归次数*每次递归中执行基本操作的次数,所以,时间复杂度是: O(2^N)。

递归的空间复杂度是: 递归的深度*每次递归所需的辅助空间的个数,所以,空间复杂度是:O(N)。

2.二分法的时间复杂度和空间复杂度

二分查找在最坏的情况下依次是n/2,n/4,n/8一直到1为止。
假设是x次,然后我们可以观察到分母是每次都乘以1/2,分子不变,所以可以列出下面等式:

n(1/2)^x = 1

通过计算得出x=log2N,即时间复杂度为O(log2N);

非递归:

public static int binarySearch(int[] arr,int toFind) {
        int left = 0;
        int right = arr.length-1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (arr[mid] < toFind) {
                left = mid + 1;
            }
            else if (arr[mid] > toFind) {
                right = mid - 1;
            }
            else {
                return mid;
            }
        }
        return -1;
    }

时间复杂度:循环的基本次数是log2N,所以,时间复杂度是O(log2N);

空间复杂度:由于辅助空间是常数级别的,所以,空间复杂度是O(1)。

递归:

public static int binarySearch(int srcArray[], int start, int end, int key) {
        int mid = (end - start) / 2 + start;
        if (srcArray[mid] == key) {
            return mid;
        }
        if (start >= end) {
            return -1;
        } else if (key > srcArray[mid]) {
            return binarySearch(srcArray, mid + 1, end, key);
        } else if (key < srcArray[mid]) {
            return binarySearch(srcArray, start, mid - 1, key);
        }
        return -1;
    }

递归的次数和深度都是log2N,每次所需要的辅助空间都是常数级别的:
时间复杂度 : O(log2N)
空间复杂度:O(log2N)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法的复杂度解析(时间复杂度和空间复杂度) 的相关文章

  • 方法返回类型前的 是什么意思?

    下面的方法返回一个List组成T类型元素 public
  • 使用 proguard 混淆文件名

    我正在使用 proguard 和 Android Studio 混淆我的 apk 当我反编译我的apk时 我可以看到很多文件 例如aaa java aab java ETC 但我项目中的所有文件都有原始名称 有没有办法混淆我的项目的文件名
  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • 为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值?

    我不明白 a 的值为0 为什么 a 不是10 那段代码的运行过程是怎样的 是否需要从Java内存模型来分析 这是我的测试代码 package com study concurrent demo import lombok extern sl
  • 有人用过 ServiceLoader 和 Guice 一起使用吗?

    我一直想通过我们的应用程序 构建系统进行更大规模的尝试 但更高的优先级不断将其推到次要地位 这似乎是加载 Guice 模块的好方法 并且避免了关于 硬编码配置 的常见抱怨 单个配置属性很少会自行更改 但您几乎总是会有一组配置文件 通常用于不
  • 什么是内部类的合成反向引用

    我正在寻找应用程序中的内存泄漏 我正在使用的探查器告诉我寻找这些类型的引用 但我不知道我在寻找什么 有人可以解释一下吗 Thanks Elliott 您可以对 OUTER 类进行合成反向引用 但不能对内部类实例进行合成 e g class
  • 我对线程失去了理智

    我想要这个类的对象 public class Chromosome implements Runnable Comparable
  • 为什么用scala写的代码比用java写的慢6倍?

    我不确定我在编写 scala 代码时是否犯了一些错误 问题是 The four adjacent digits in the 1000 digit number that have the greatest product are 9 9
  • ThreeTen 向后移植与 JSR-310 的比较

    由于某些原因 我们现在无法使用 java 8 我们仍然停留在 java 7 上 不过 我想使用新的JSR 310 date time APIs现在 使用官方向后移植 ThreeTen http www threeten org threet
  • 在 Spring 中为 @Pathvariable 添加类级别验证

    在发布这个问题之前 我已经做了很多研究并尝试了很多可用的解决方案 这是我陷入的棘手情况 我有一个 Spring 控制器 它有多个请求映射 它们都有 PathVariables 控制器如下所示 Controller EnableWebMvc
  • 使用 JDBC 连接到 PostgreSql 的本地实例

    我在 Linux 机器上有一个正在运行的 PostgreSql 本地实例 当我使用psql来自 shell 的命令我成功登录 没有任何问题 我需要通过 JDBC 连接到 PostgreSql 但我不知道我到底应该传递什么url参数为Driv
  • 类更改(例如字段添加或删除)是否保持 Serialized 的向后兼容性?

    我有一个关于 Java 序列化的问题 在这种情况下 您可能需要修改可序列化类并保持向后兼容性 我有丰富的 C 经验 所以请允许我将 Java 与 NET 进行比较 在我的Java场景中 我需要使用Java的运行时序列化机制序列化一个对象 并
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • 用于请求带有临时缓存的远程 Observable 的 RxJava 模式

    用例是这样的 我想暂时缓存最新发出的昂贵的Observable响应 但在它过期后 返回到昂贵的源Observable并再次缓存它 等等 一个非常基本的网络缓存场景 但我真的很难让它工作 private Observable
  • 在 Java 中通过 D-Bus MPRIS 访问 Clementine 实例

    我使用 Clementine 作为音乐播放器 它可以通过 D Bus 命令进行控制 在命令行上 使用 qdbus 我可以 Start Stop 暂停播放器 强制它跳过播放列表中的歌曲 检查播放列表的长度 检查播放列表中当前播放的曲目及其元数
  • 使用 Apache 允许 Glassfish 和 PHP 在同一服务器中协同工作

    是否可以建立从 Java 到 php 文件的桥梁 我有一个用 Java 编写的应用程序 我需要执行http piwik org http piwik org 这是用 PHP 编写的 在服务器中 我正在运行 PHP 但无法从浏览器访问 php
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 设置 TreeSet 的大小

    有没有办法像数组一样对 Java 集合中的 TreeSet 进行大小限制 例如我们在数组中 anArray new int 10 数组具有固定长度 在创建数组时必须指定该长度 A TreeSet当您向其中添加元素时会自动增长 您无法设置其大

随机推荐

  • 最新!Photoshop 2022 (ps2022)中文

    Photoshop 2022拥有超强的图片编辑功能 对图片调整强度 饱和度 亮度 从照片编辑和合成到数字绘画 动画和图形设计 只要能想到 就能在Photoshop中创作出来 包括神经滤镜 天空更换以及增强的云文档等 可以让设计者的工作更加高
  • ORA-01502: 索引或这类索引的分区处于不可用状态

    一 问题描述 插入数据时 出现如下报错 ORA 01502 索引或这类索引的分区处于不可用状态 英文 ora 01502 index schema index name or partition of such index is in un
  • (五)unity shader基础之——————学习shader所需的数学基础:下篇(坐标空间:模型空间、世界空间、观察空间、裁剪空间、屏幕空间、法线变换等)

    一 坐标空间 上篇文章讲述了如何使用矩阵来表示基本的变换 如平移 旋转和缩放 在本节我们将关注如何使用这些变换来对坐标空间进行变换 渲染游戏的过程可以理解成是把一个个顶点经过层层处理最终转换为屏幕上的过程 本节我们就将学习这个转换过程是如何
  • Python类和对象编写一个小游戏【含注释】

    定义一个鱼类和龟类并编写游戏 假设游戏场景为范围 x y 为0 lt x lt 10 0 lt y lt 10 游戏生成1只乌龟和10条鱼 它们的移动方向均随机 乌龟的最大移动能力是2 Ta可以随机选择1还是2移动 鱼儿的最大移动能力是1
  • 集合--10万随机数问题

    1 求十万个数据每个数据出现的次数 import java util ArrayList import java util Random import java util HashMap import java util Iterator
  • torch.optim.SGD()

    其中的SGD就是optim中的一个算法 优化器 随机梯度下降算法 PyTorch 的优化器基本都继承于 class Optimizer 这是所有 optimizer 的 base class torch optim是一个实现了各种优化算法的
  • QT之Excel表格操作

    QT之Excel表格操作 提前准备 打开读取excel文件 写入保存excel文件 提前准备 pro文件中添加 QT axcontainer 在需要使用excel的文件中添加 include
  • GitLab 仓库管理 创建一个仓库详细步骤

    Gitlab 仓库管理 GitLab 是通过组 group 的概念来统一管理仓库 project 和用户 user 通过创建组 在组下再创建仓库 再将用户加入到组 从而实现用户与仓库的权限管理 创建仓库之前先创建组 创建组 New grou
  • 状态空间模型

    一 状态空间模型简述 状态空间模型是动态时域模型 以隐含着的时间为自变量 状态空间模型包括两个模型 一是状态方程模型 反映动态系统在输入变量作用下在某时刻所转移到的状态 二是输出或量测方程模型 它将系统在某时刻的输出和系统的状态及输入变量联
  • html文字下排输入,HTML input text单行文本输入框简介说明

    摘要 下文讲述html代码中input type text 时的相关属性简介说明 如下所示 input type text 简介 当 input标签中 type text 时 代表此标签是一个单行文本输入框 单行文本框还包括一些属性 如下
  • 新项目需求调研

    从三个方面帮你建立起了对这个项目基本认识 概念层面 何谓访客管理系统 产品层面 访客管理系统通常有啥功能 客户层面 什么样的目标客户会产生这种需求 需求调研四个维度 那么 了解了这些基本信息后 我们就可以开展需求调研了吗 显然是不够的 对于
  • 三菱fx2n64mr说明书_三菱PLC模块FX3U-64MR/DS使用手册

    三菱PLC模块FX3U 64MR DS使用手册 FX1N 24MR 001 是三菱PLC FX1N系列 是一种卡片大小的PLC 适合在小型环境中进行控制 它具有的性能 串行通讯功能以及紧凑的尺寸 这使得它们能用在以前常规PLC无法安装的地方
  • 代码随想录--哈希--四数相加II

    给定四个包含整数的数组列表 A B C D 计算有多少个元组 i j k l 使得 A i B j C k D l 0 为了使问题简单化 所有的 A B C D 具有相同的长度 N 且 0 N 500 所有整数的范围在 2 28 到 2 2
  • 用DOS命令合并多个文本文件

    作者 iamlaosong 从总部系统下的干线数据 有30个文本文件 希望变成一个Excel文件 方法是先用copy命令将文本合成一个 再用excel打开 最后保存为Excel文件 步骤如下 1 将所有的文本文档拷贝到同一个文件夹 然后单击
  • 半透明信息显示浮动窗口的实现

    实现目的 在一些画图软件中 经常需要向用户展示鼠标移动到的位置的对象的一些参数信息 此时 完成一个交互性友好的信息显示界面就相当的重要了 因为一个软件的好坏 在用户的眼中 第一感觉甚至是第一重要的就是视觉效果和可操作性 当然 软件本身的稳定
  • 阿里云轻量应用服务器防火墙配置(全网最简单)

    阿里云轻量应用服务器防火墙配置 1 命令行配置 1 开启防火墙 systemctl start firewalld 2 限制端口 firewall cmd zone public add port 5672 tcp permanent 开放
  • 过拟合:所表现的就是模型训练误差很小,但测试误差很大,对于产生这种现象以下说法正确

    过拟合 所表现的就是模型训练误差很小 但测试误差很大 对于产生这种现象以下说法正确 提示 基础知识 1 深度学习机器学习笔试面试知识 正则化 文章目录 过拟合 所表现的就是模型训练误差很小 但测试误差很大 对于产生这种现象以下说法正确 TO
  • 关于echarts 图,在切换tab后,返回时宽度变窄的问题

    项目场景 提示 这里简述项目相关背景 最近在做一个统计报表的项目 需要插入ECharts 图表和表格做统计 并且可以导出Excel 表格 问题描述 提示 这里描述项目中遇到的问题 在开发过程中 碰到了一个 echarts 图在切换到 tab
  • KubeEdge环境搭建(支持网络插件flannel)

    KubeEdge环境搭建 准备工作 K8s集群环境搭建 准备开始 配置国内镜像 仅amd64架构 如果是arm架构的不要更改镜像 安装docker 安装K8s 初始化Master节点 网络插件安装 部署可视化KuBoard Cloud节点配
  • 算法的复杂度解析(时间复杂度和空间复杂度)

    时间复杂度与空间复杂度 1 算法的复杂度 2 时间复杂度 1 大O表示法 2 大O推导方法 3 一些常见的大O运行时间 3 空间复杂度 4 个别特殊举例 1 斐波那契数列的时间和空间复杂度 2 二分法的时间复杂度和空间复杂度 1 算法的复杂