Java时间复杂度和空间复杂度(详解)

news2025/1/27 12:40:13

目录

1.复杂度分析

2.时间复杂度

大O的渐进表示法

3.空间复杂度


1.复杂度分析

当我们设计一个算法时,怎样衡量其好坏?

算法在编写为可执行程序后,运行时需要耗费时间资源和空间(内存)资源。因此,衡量一个算法的好坏,一般是从时间空间两个方面来衡量。

2.时间复杂度

一个算法执行所需要的时间,我们可以将代码跑一遍得到具体的时间,但是如果每一个算法都测试一遍的话,十分耗费时间和精力,而且,其测试的结果高度依赖于测试环境,测试环境中的硬件不同会影响测试结果,测试数据的规模也会影响测试结果。

如果我们假设每行代码执行的时间都相同,那么此时影响时间的因素为语句的执行次数,即时间与其语句的执行次数成正比例

时间复杂度:算法中的基本操作的执行次数

public static int factorial(int N){
        int ret = 1;
        for (int i = 2; i <= N; i++) {
            ret *= i;
        }
        return ret;
    }

上述代码用来求n的阶乘,其中,在for前的代码每行执行了一次,在for循环(i++)及其中的代码(ret *= i)每行执行了N-1次,那么该代码总执行了(1+2*(N-1))次,即(2*N-1)次,代码具体执行了多少次,与传入数据n相关。

当 N = 100 时,代码执行 199 次

当 N = 1000时,代码执行 1999次

当 N = 10000时,代码执行 19999次

……

N越大,常数 -1,系数2对执行次数的影响越小。

因此,我们在计算时间复杂度时,并不需要计算精确的执行次数,只需要计算出其大概执行的次数,我们用大O的渐进表示法来表示

大O的渐进表示法

大O符号(Big O notation):用于描述函数渐进行为的数学符号

推导大O阶方法:

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

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

3.如果最高阶项存在且不是1,则去除与这个项目相乘的常数

例如,上述求阶乘的代码中,其执行次数为 2*N-1,用大O的渐进表示法,去掉对结果影响不大的项 -1,最高阶项去除与其相乘的常数,即为O(N)

在算法中,存在不同的执行情况,

例如在长度为N的数组中查找数据x时,可能执行一次就找到,也可能执行n次也找不到

我们将其分为最好、平均和最坏情况

最好情况:任意输入规模的最小运行次数

平均情况:任意输入规模的期望运行次数

最坏情况:任意输入规模的最大运行次数

而我们一般关注的是算法的最坏运行情况

我们通过一些例子来进一步熟悉大O的渐进表示法:

由于我们需要去掉对结果影响不大的项,因此我们可以不再分析对结果影响较小的语句。

例1:

public static int add(int a, int b){
        int ret = a+b;
        return ret;
    }

上述代码一共执行两次,用常数1取代其中的常数,即为 O(1)

例2:

 int fun(int N,int M){
        int count = 0;
        for (int i = 0; i < N; i++) {
            count++;
        }
        for (int i = 0; i < M; i++) {
            count++;
        }
        return count;
    }

上述代码一共有两个for循环,其中对执行次数影响最大(即执行次数最多)的语句为count++,共共执行了 N+M 次,

当 N 远大于 M时,时间复杂度为 O(N)

当 M 远大于 N时,时间复杂度为 O(M)

当 M 与 N 差不多大时,时间复杂度为 O(M+N)

由于没有说明N与M的大小关系,时间复杂度为 O(N+M)

例3:

    void fun(int N){
        int count = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < i; j++) {
                count += j;
            }
        }
    }

 上述代码中有一个嵌套循环,其中对执行次数影响最大的语句为 count += j,我们对其进行分析

当 i = 0 时,语句执行 0 次,

当 i = 1 时,语句执行 1 次,

当 i = 2 时,语句执行 2 次,

……

当 i = N-1时,语句执行 N-1次

则总执行次数为 0 + 1 + 2 + …… + N-1,利用等差数列求和公式,可得结果为\frac{(N-1)*N}{2},最高阶项为\frac{^{N{_{}}^{2}}}{2},去掉系数,时间复杂度为 O(N^2)

例4:


    void fun(int M){
        int count = 0;
        for (int i = 0; i < 10; i++) {
            count++;
        }
    }

 时间复杂度为O(1)

注意!count++ 语句一共执行了10次,与M没有关系

例5:

  
    public static int binarySearch(int[] arr, int x){
        if(arr.length == 0){
            return -1;
        }
        int left = 0;
        int right = arr.length-1;
        while(left <= right){

           int mid = left + ((right-left)>>1);
            if(arr[mid] == x){
                return mid;
            }else if(arr[mid] > x){
                right = mid;
            }else{
                left = mid+1;
            }
        }
        return -1;
    }

上述代码为二分查找,考虑最坏的情况,即查找不到:

我们先分析二分查找是如何查找数据的:

二分查找的前提是被查找的数组arr有序,通过确定中间位置mid,将数组分为两个部分,若被查找值x < arr[mid],则排除右边部分值,在左边继续进行二分查找;若x > arr[mid],则排除左边部分值,在右边继续进行二分查找;若 x = arr[mid],则找到被查找值,返回即可。

过程如下图所示:

由于一次二分查找会排除数组一半的元素,即

N/2

N/4

N/8

……

1 当结果为1时循环结束

因此 1*2*2*……*2 = N,即 2^x = N,则执行次数x = {log_{2}}^{}N

时间复杂度为O(log_{2}^{}N)

例6:

    long factorial(int N){
        return N < 2? N: factorial(N-1)*N;
    }

 上述递归的结束条件为 N < 2,当N >= 2时,会一直递归下去:

N

N-1

N-2

……

2

1 此时递归结束

递归的次数为N,因此时间复杂度为O(N)

例7:

    int fibonacci(int N){
        return N < 2? N: fibonacci(N-1)+ fibonacci(N-2);
    }

斐波那契递归,可将其看成一个二叉树,将其递归时开辟的栈帧看作一个节点,每一个节点就是一次函数调用,则递归的时间复杂度为二叉树结点个数,具体递归过程为:

 

其中最后一层可能不满,由于计算时间复杂度只需要计算出其大概执行的次数,最后一层的空缺对计算的影响可以忽略不计

则递归的次数为Fib(N) = 2^0 + 2^1 + ……+ 2^(N-1) 

 利用等比数列求和公式,可得2^n - 1,则时间复杂度为O(2^N)

3.空间复杂度

空间复杂度是对一共算法在运行过程中临时占用存储空间大小的量度。空间复杂度计算的是变量的个数,其计算规则基本与时间复杂度类似,也使用大O的渐进表示法

例1:

    void fun(int N){
        int count = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < i; j++) {
                count += j;
            }
        }
    }

 其中开辟了常数个额外的变量(count、i、j),因此空间复杂度为O(1)

例2:

    int[] fun(int N){
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = i;
        }
        return arr;
    }

 开辟了一共大小为N的整形数组和常数个额外的变量,因此空间复杂度为O(N)

例3:

    long factorial(int N){
        return N < 2? N: factorial(N-1)*N;
    }

上述代码递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间,因此空间复杂度为O(N)

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

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

相关文章

【深度学习】 Python 和 NumPy 系列教程(五):Python容器:3、集合Set详解(初始化、访问元素、常用操作、常用函数)

目录 一、前言 二、实验环境 三、Python容器&#xff08;Containers&#xff09; 0、容器介绍 1、列表&#xff08;List&#xff09; 2、元组&#xff08;Tuple&#xff09; 3、集合&#xff08;Set&#xff09; 1. 初始化 2. 访问集合元素 3. 常用操作 a. 添加单个…

文件上传漏洞第十六关十七关

第十六关 第十七关 第十六关 直接上传php文件判断限制方式&#xff1a; 同第十五关白名单限制 第十六关源码&#xff1a; 代码逻辑判断了后缀名、content-type&#xff0c;以及利用imagecreatefromgif判断是否为gif图片&#xff0c;最后再做了一次二次渲染 二次渲染图片马&…

Linux虚拟机能ping通开发板的网络环境配置

Linux虚拟机能ping通开发板的网络环境配置 设备&#xff1a;Win10本地PC、ubuntu虚拟机、ARM linux开发板目标&#xff1a;三者可以互相ping通&#xff0c;即为搭建好了此网络环境预分配网段&#xff1a;192.168.1.1 - 192.168.1.255 本地PC:192.168.1.10 虚拟机&#xff1a;1…

关于GitHub Desktop中的“Open in Git Bash”无法使用的问题

问题描述 在GitHub Desktop中选择Repository--Open in Git Bash&#xff08;如图1&#xff09;&#xff0c;出现如图2所示结果。 图1 图2 解决办法&#xff08;Windows10&#xff09; 这个问题是由于Git的环境变量没有得到正确配置所导致的&#xff0c;所以需要正确设置环境变量…

Java线程之间通信方式

目录 1 线程之间的通信方式主要有以下几种2 共享变量3 锁机制4 条件变量5 信号量6 管道 1 线程之间的通信方式主要有以下几种 在实际开发时&#xff0c;一个进程中往往有很多个线程&#xff0c;大多数线程之间往往不是绝对独立的&#xff0c;比如说我们需要将A和B 两个线程的执…

C3d,C4d,C5d;

cl08267: ISOPREN_C2_like Superfamily

HBase 记录

HBase 管理命令 hbase hbck -details TABLE_NAME hbase hbck -repair TABLE_NAMEHBase概览 Master、RegionServer作用 RegionServer与Region关系 数据定位原理 https://blogs.apache.org/hbase/entry/hbase_who_needs_a_master RegionServer HBase Essentials.pdf (P25)…

解锁智慧照明新玩法,Construlita携手涂鸦智能打造创新方案!

近日&#xff0c;墨西哥头部照明品牌Construlita Lighting International SA DE CV&#xff08;以下简称&#xff1a;Construlita&#xff09;与全球化IoT开发者平台涂鸦智能&#xff08;NYSE: TUYA&#xff0c;HKEX: 2391&#xff09;在Construlita Connect发布会上宣布达成合…

Stable Diffusion 告别猜关键词,LoRA适配关键词自动生成

有没有想想过在SD绘图的时候下载好的LoRA模型选择之后不生效是为什么?或者说关键词不知道怎么填写? 这里介绍基于 Civitai 的LoRA 使用方法。 文章目录 Civitai 插件使用方法Civitai 插件 如果没有安装的小伙伴可以参考前面的文章先对 Civitai 的模型管理进行安装和使用,确…

龙芯指令集LoongArch——学习笔记(1)

1 龙芯架构 PDF下载链接&#xff1a; https://www.loongson.cn/download/index 1.1 龙芯架构概述 龙芯架构具有 RISC 指令架构的典型特征。 它的指令长度固定且编码格式规整&#xff0c; 绝大多数指令只有两个源操作数和一个目的操作数&#xff0c; 采用 load/store 架构&…

代码随想录算法训练营day42 | 动态规划 背包问题 01背包 二维数组一维数组 |416. 分割等和子集

动态规划&#xff1a;背包理论 背包理论基础 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。 如果这几种背包&#xff0c;分不清&#xff0c;我这里画了一个图&#xff0c;如下&#xff1a; 而完…

Unity 从0开始编写一个技能编辑器_01_分析需求

入职以来一直很想实现一个技能编辑器&#xff0c;在积累了一些经验以后&#xff0c;决定利用ScriptableObject开发一个&#xff0c;在此记录 1.简单的需求分析 在游戏开发中&#xff0c;技能系统是一个至关重要的组成部分。技能决定了游戏角色可以执行的各种动作&#xff0c;例…

【深入理解Linux内核锁】八、完成量

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1、完成量API2、API实现2.1 completion2.2 init_completion2.3 wait_for_com…

运行速度终于变快了!优化VMD参数,五种适应度函数任意切换,最小包络熵、样本熵、信息熵、排列熵、排列熵/互信息熵...

经常有小伙伴后台留言&#xff0c;说优化VMD参数的程序为什么运行时间辣么长&#xff0c;有没有办法改善一下&#xff01; 今天小淘就为大家带来了改善运行时间的方法&#xff1a;采用官方自带的vmd函数 这是MATLAB官方自带的VMD函数截图&#xff0c;可以看到只有2020a版本以后…

【JAVA】 图书管理系统(javaSE简易版 内含画图分析) | 期末大作业课程设计

作者主页&#xff1a;paper jie 的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVA》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

SLAM从入门到精通(ROS安装)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 ROS科研上面用的多&#xff0c;实际生产其实用的也不少。它本身还是很好的应用框架。当然&#xff0c;它对于很多初学的同学来说还是很友好的。学完…

管理类联考——数学——汇总篇——知识点突破——工程

⛲️ 工程问题是应用题中仅次于路程问题的一个常考点&#xff0c;既是重点&#xff0c;也是难点。其主要的基本关系式为&#xff1a; 工作时间 工作效率 工作量 工作时间工作效率工作量 工作时间工作效率工作量。 本专题主要学习复杂的工程问题&#xff0c;主要有以下三种方…

【动手学深度学习】--机器翻译与数据集

文章目录 机器翻译与数据集1.下载和预处理数据集2.词元化3.词表4.加载数据集5.训练模型 机器翻译与数据集 学习视频&#xff1a;机器翻译数据集【动手学深度学习v2】 官方笔记&#xff1a;机器翻译与数据集 机器翻译&#xff08;machine translation&#xff09;指的是 将序…

absolute和relative元素层级问题

布局层级问题 同一个父元素的两个子元素&#xff0c;一个是absolute布局&#xff0c;一个是relative布局&#xff0c;为啥relative元素在absolute元素的背景色之上&#xff1f; 实例&#xff1a; <div id"father">father<div id"c1">c1-absolu…

人工智能海洋中的塞壬之歌:大型语言模型LLM中的幻觉研究综述(一)

“ 大型语言模型LLM 如 ChatGPT 已经得到了广泛的应用&#xff0c;涵盖了诸多应用领域。但也存在生成内容与事实不符的幻觉问题。这种幻觉包括输入冲突、语境冲突以及与事实相冲突的情况&#xff0c;给实际需求和应用构建带来了挑战。一篇最新的论文《Sirens Song in the AI Oc…