首页 > 编程语言 > 算法之空间复杂度以及评判算法的标准(Java)

算法之空间复杂度以及评判算法的标准(Java)

时间:2023-10-18 22:31:59浏览次数:37  
标签:fun4 Java 复杂度 整数 算法 空间 method

一:概述

//例如:给出一些整数n:3 1 2 5 4 9 7 2,其中
//有两个整数是重复的,要找出这两个重复地整数。
// 对于这个简单的需求,可以使用很多的思路类解决,其中最朴素的就是
//双重循环
//遍历整个数列,每遍历一个新的整数就开始回顾
// 之前遍历过的所有整数。
//即 第1步:遍历整数3,前面没有数字,所有无须回顾比较
//   第2步:遍历整数1,回顾前面的数字3,没有发现重复的数字
//   第3步:遍历整数2,回顾前面的数字3、1,没有发现重复的数字
//  ....
// 后续的步骤跟上面的相似,一直遍历到最后的整数2
// 发现和前的整数2重复
// 通过双重循环可以得到最终的结果但是并不是一个好的算法
// 为了提高运行速率,我们需要引入中间数据
/*
  当遍历整个数列时,每遍历一个整数时,每遍历一个整数,
  就把整数存储起来,起来像放到字典中一样。当遍历下一个整数时
  不必再慢慢向前回溯比较,而直接去“字典”中查找,看有没有对应的整数即可
  假如已经遍历的前7个整数,那么字典里面存储的信息为:
  key value
  3    1
  1    1
  2    1
  5    1
  4    1
  9    1
  7    1

"字典"左侧的key代表整数值,“字典”右侧的Value代表该整数出现的次数(也可以只记录key)

接下来,当遍历最后一个整数2时,从“字典”中可以轻松找到2曾经出现过。

由于读写“字典”本身的时间复杂度是O(1),所以真个算法的时间复杂度为O(n),

和最初的双重循环相比,运行效率大大提高了。而这个所谓的“字典”,是一种比较特殊的数据结构

,叫做散列表。这个数据结构需要开辟一定的内存空间来存储有用的信息

但是,内存空间是有限的,在时间复杂度相同的情况下,算法占用的空间自然是越小越好

。如何描述一个算法占用的内存空间的大小呢?这就引申出来了算法的另一个重要指标-空间复杂度

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

它同样使用O表示法

程序占用空间大小的计算公式记作为S(n) =O(f(n)),其中n为问题的规型,f(n)为算法所占用

存储空间的函数

二:空间复杂度的计算

具体问题需要具体分析。和时间复杂度类似
 空间复杂度也有几种不同的增长趋势。
 */
// 常见的空间复杂度有以下的几种情形。

    public static void main(String[] args) {


    }


    //1. 常量空间
// 当算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记作O(1)
// 例如下面程序
    public void fun1(int n) {
        int var = 3;

    }


    // 2. 线性空间
//当算法分配的空间是一个线性的集合(如数组),并且结合的大小和输入规模n成正比时
//空间复杂度记作O(n),例如下面的程序
    public void fun2(int n) {
        int[] array = new int[n];

    }

    // 3. 二维空间
    /*
      当算法分配的空间是一个二维数组集合,并且集合的长度和宽度都与输入规模n成正比时
      空间复杂度记作为O(n^2)
      例如下面的程序
     */
    public void fun3(int n) {
        int[][] matrix = new int[n][n];
    }

    //4. 递归空间
    /*
     递归空间是一个比较特殊的场景,虽然递归代码中并没有
     明显式地声明变量和集合,但是计算机在执行程序的时候
     会专门分配一块内存,用来存储为“方法调用栈”

     “方法调用栈”包括进栈和出栈两个行为:
      当进入一个新方法时,执行入栈操作,把调用的方法和参数信息从栈中弹出
      当返回方法时,执行出栈操作,把调用的方法和参数信息从栈中弹出
      下面是一个标准的执行的递归程序:
     */

    public void fun4(int n) {
        if (n <= 1) {
            return;
        }
        fun4(n - 1);
    }
代码分析:假如初始传入参数值为n = ,那么方法fun4(参数n=5)的调用信息先入栈
                   method fun4
                     n      5
接下来递归调用相同方法,方法fun4(参数n=4)的调用信息入栈。
                   method    fun4
                      n        4
                   method      fun4
                      n         5
依次类推,递归越来越深,入栈的元素越来越多。
                     method    fun4
                       n        1
                     method     fun4
                       n        2
                     method     fun4
                       n         3
                       method     fun4
                       n         4
                        method     fun4
                       n         5
               当n = 1时,达到递归结束条件,执行return指令,方法近栈。
                  method     fun4
                       n        2
                     method     fun4
                       n         3
                       method     fun4
                       n         4
                        method     fun4
                       n         5
                   最终,“方法调用栈”的全部元素会--出栈
                    由上面”方法调用栈“的出入栈过程可以看出,执行递归操作
                    所需要的内存空间和递归的深度成正比。纯粹的递归操作的空间复杂度也是现行的,
                    如果递归深度的深度为n,那么空间复杂度就是O(n)

三:时间复杂度和空间复杂度的必要性与算法的关系

人们之所以花大量的力气去评估算法的时间复杂度和空间复杂度,其根本

原因就是计算机的运行速度和空间资源是有限的。

就如一个大财主,基本不必为日常花销伤脑筋,而一个没多少积蓄

的普通人,则不得为日常花销精打细算。

对于计算机系统来说如此。虽然目前计算机的CPU处理速度不断飙升,

内存和硬盘空间也越来越大,但是面对庞大而复杂的数据和业务,我们仍然

要精打细算,选择最有效的的利用方式。

双重循环的时间复杂度是O(n^2),空间复杂度是O(1),这属于

牺牲空间来换取时间的情况。

相反,字典法的空间复杂度是O(n),时间复杂度是O(n),这属于牺牲空间

来换取时间的情况,在大多数情况的时候,时间复杂度是O(n),这属于牺牲空间来换取时间的情况

在绝大多数的时候,时间复杂度更为重要些,宁可多分配一些空间,也要提升程序的执行速度

空间复杂度就离不开数据结构。

四:算法初识总结

什么是算法?

在计算机领域里,算法是一系列程序指令,用于处理特定的运算和逻辑问题

衡量算法优劣的主要标准是时间和空间复杂度

什么是数据结构?

数据结构是数据的组织、管理和存储格式,其使用的目的是为了高效地的访问和修改数据

数据结构包含数组、链表这样的线性结构,也包含树、图这样的复杂数据结构

什么是时间复杂度?

时间复杂度是对一个算法运行时间的长短的量度,用大O表示,记作T(n) = O(f(n))

常见的时间复杂度的从低到高排序为:O(1) 、O(logn)、O(n)、O(nlogn) 、O(n^2)

什么是空间复杂度?

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,用大O表示,记作S(n)=O(f(n))

常见的空间复杂度按照从低到高的顺序排列为:O(1)、O(n)、O(n^2)等。其中递归算法的空间复杂度

和递归深度成正比



标签:fun4,Java,复杂度,整数,算法,空间,method
From: https://blog.51cto.com/u_15912723/7924044

相关文章

  • 23.10.18(常用Java异常处理情况整合)
    在JAVA项目中,异常处理是一项非常重要的任务。合理处理异常能够提高程序的稳定性和可靠性,保证程序的正常运行。下面是关于JAVA项目中常用的异常处理情况的总结:1.空指针异常(NullPointerException):在使用一个空对象的成员变量或方法时会抛出该异常。可以通过判断对象是否为空来避免......
  • javaweb第10章源码
    javaweb第10章源码下载链接:https://wwpv.lanzoue.com/iDhBE1c5hcxg文件结构CHAPTER10│.classpath│.project│chapter10.iml│├─.idea│encodings.xml│misc.xml│modules.xml│workspace.xml│├─.settings│.jsdtscope......
  • C#桶排序算法
    前言桶排序是一种线性时间复杂度的排序算法,它将待排序的数据分到有限数量的桶中,每个桶再进行单独排序,最后将所有桶中的数据按顺序依次取出,即可得到排序结果。实现原理首先根据待排序数据,确定需要的桶的数量。遍历待排序数据,将每个数据放入对应的桶中。对每个非空的桶进行排......
  • 23.10.18 Java当中的异常处理
    Java当中的异常处理在Java中,异常是指在程序执行期间发生的错误或异常情况,可以分为两种类型:受检异常(CheckedException)和非受检异常(UncheckedException)。受检异常:受检异常是指需要在代码中显式处理的异常,通常继承自Exception类的子类。例如,IOException和SQLException是受检异......
  • MAML算法概述
    MAML算法概述什么是MAML1.论文地址:Model-AgnosticMeta-LearningforFastAdaptationofDeepNetworks2.要解决的问题小样本问题模型收敛过慢3.算法描述​ MAML期望通过训练一组初始化参数,使得模型透过训练出的初始化参数,未来在少量样本基础上实现快速收敛。该初......
  • 在JavaScript中,`!!`(不是not)操作符的作用是什么?
    内容来自DOChttps://q.houxu6.top/?s=在JavaScript中,!!(不是not)操作符的作用是什么?我看到了一些代码,似乎使用了我不知道的操作符,形式为两个感叹号,就像这样:!!。有人能告诉我这个操作符是做什么的吗?我看到这个操作符的上下文是:this.vertical=vertical!==undefined?!!ver......
  • javacv入门
    第一章:javacv介绍了解javacv的历史和发展背景JavaCV是一个开源的Java框架,它提供了基于Java的接口,用于访问各种计算机视觉库和工具包,如OpenCV、FFmpeg等。JavaCV旨在为Java开发人员提供快速、简单和可靠的图像和视频处理能力。JavaCV的历史可以追溯到2007年,当时一个名为“JavaCP......
  • docker入门加实战—部署Java和前端项目
    docker入门加实战—部署Java和前端项目部署之前,先删除nginx,和自己创建的dd两个容器:dockerrm-fnginxdd部署Java项目作为演示,我们的Java项目比较简单,提供了一个接口:配置文件连接docker里的mysql:打包如下:DockerFIle文件如下:#基础镜像FROMopenjdk:11.0-jre-buster......
  • 算法笔记-有效括号序列题解
    描述给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列。括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。数据范围:字符串长度0≤n≤10000要求:空间复杂度O(n),时间复杂......
  • 《Java 8实战》PDF高清高质量电子书
    下载:https://pan.quark.cn/s/c6c7603af158......