算法之空间复杂度以及评判算法的标准(Java)
  kIM7GUNpnV3x 2023年11月02日 23 0

一:概述

//例如:给出一些整数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)等。其中递归算法的空间复杂度

和递归深度成正比



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
kIM7GUNpnV3x