美文网首页
01:复杂度:如何衡量程序运行时的效率

01:复杂度:如何衡量程序运行时的效率

作者: Benedict清水 | 来源:发表于2020-05-25 22:50 被阅读0次

写在前面

在python语言中,并没有直接使用数组这个概念,而是使用列表(list)和元祖(tuple)这两种集合,他们本质上都是对数组的封装。后文中提到的数组概念,对应的是python语言的中的列表(list)。

一、复杂度的定义

复杂度是一个关于输入数据量n的函数 。假设你的代码的复杂度是f(n),那么就用大写字母O和括号,把f(n)括起来就可以了,即O(f(n))。例如,O(n)表示的是,复杂度与计算实例的个数n线性相关;O(logn)表示的是,复杂度与计算实例的个数n对数相关。
通常复杂度的计算方法遵循以下几个原则:

  • 首先,复杂度与具体的常系数无关,例如O(n)和O(2n)表示的是同样的复杂度。我们详细分析一下,O(2n)=O(n+n)=O(n)+O(n),也就是说,一段O(n)复杂度的代码是先后执行两遍O(n),其复杂度是一致的。
  • 其次,多项式级的复杂度相加的时候,选择最高项作为结果,例如O(n2)+O(n)和O(n)表示的是同样的复杂度。因为O(n2)+O(n)=O(n2+n)。随着n越来越大,二阶多项式的变化率是比一阶多项式更大的,因此可以省略一阶多项式。
  • 最后,O(1)页表示一个特殊复杂度,含义为某个任务通过有限可数的资源即可完成。此处有限可数的具体含义是:与输入数据量n无关
  1. 例题:对于输入的数组,输出与之逆序的数组。例如,输入 a=[1,2,3,4,5],输出[5,4,3,2,1]
  • 方法一:建立并初始化数组b,得到一个与输入输入数组等长的全零数组。通过一个for循环,从左到右将a数组的元素,从右到左地赋值到b数组中,最后输出数组b得到结果。
    代码如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
def void_s1_1():
    a = [1,2,3,4,5]
    b = list()
    for index,value in enumerate(a):
        b.append(a[len(a)-index-1])
    print(b)
if __name__ == "__main__":
    void_s1_1()

这段代码的输入数据是a,数据量就等于数组a的长度。代码中有一个for循环,作用是给数组b赋值,其执行次数与数据量相等,因此,代码的时间复杂度就是O(n)。
空间方面的主要体现在计算过程中,对于存储资源的消耗情况。上面代码我们定义了一个新的数组b,它与输入的数组a的长度相等。因此,空间复杂度就是O(n)。

  • 方法二:定义一个缓存变量tmp,接着通过一个for循环,从0遍历到a数组长度的一半(即len(a)/2)。每次遍历就是交换收尾对相应的元素。最后打印数组a,得到结果。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def void_s1_2():
    a = [1,2,3,4,5]
    for index in range(len(a)/2):
        tmp = a[index]
        a[index] = a[len(a)-index-1]
        a[len(a)-index-1] = tmp
    print(a)
        
if __name__=="__main__":
    void_s1_2()

这段代码包含了一个for循环,执行的次数是数组长度的一半,时间复杂度变成了O(n/2)。根据复杂度与具体的常系数无关的性质,这段代码的时间复杂度也就是O(n)。
空间方面,我们定义了一个tmp变量,它与数组长度无关。也就是,输入是5个元素的数组,需要一个tmp变量;输入是50个元素的数组,依然需要一个tmp变量。因此,空间复杂度与输入数组长度无关,即O(1)。

二、时间复杂度与代码结构的关系

  • 例1,定义一个数组a = [1,4,3],查找数组a中的最大值,代码如下:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def void_s1_3():
    a = [1,4,3]
    max_val = a[1]
    for value in a:
        if value > max_val:
            max_val = value
    print(max_val)
        
if __name__=="__main__":
    void_s1_3()

这个简单的例子实现方法就是,暂存当前最大值并把所有元素遍历一遍即可。因为代码结构上需要使用一个for循环,对数组虽有元素处理一遍,所以时间复杂度为O(n)。

  • 例2,定义一个数组a=[1,3,4,3,4,1,3],查找数组中出现次数最多的那个数字
#!/usr/bin/python
# _*_coding:utf-8 _*_
def void_s1_4():
    a = [1, 3, 4, 3, 4, 1, 3]
    val_max = -1
    time_max = 0
    for i in range(len(a)):
        time_tmp = 0
        for j in range(len(a)):
            if a[i] == a[j]:
                time_tmp = time_tmp + 1
            if time_tmp > time_max:
                time_max = time_tmp
                val_max = a[i]
    print(val_max, time_max)
if __name__ == "__main__":
    void_s1_4()

这段代码,采用了双层循环的方式进行计算:第一层循环,我们对数组中的每个元素进行遍历;第二层循环,对于每个元素计算出现的次数,并且通过当前元素次数time_tmp和全局最大次数变量time_max的大小关系,持续保存出现次数最多的那个元素及其出现次数。由于是双层循环,这段代码在时间方面消耗就是n*n的复杂度,也就是O(n2)

  • 经验性结论:

1.一个顺序结构的代码,时间复杂度是O(1)。
2.二分查找,或者更通用地说是采用分而治之的二分策略,时间复杂度都是O(logn)。
3.一个简单的for循环,时间复杂度是O(n)。
4.两个顺序执行的for循环,时间复杂度是O(n)+O(n)=O(2n),其实也是O(n)。
5.两个嵌套的for循环,时间复杂度是O(n2)

小结

  • 什么是时间复杂度
    时间复杂度是对一个算法运行时间的长短的量度,用大O表示,记做T(n)=O(f(n))。常见的时间复杂度按照从低到高的顺序,包括O(1)、O(logn)、O(n)、O(nlogn)、O(n2)
  • 什么是空间复杂度
    空间复杂度是对一个算法在运行的过程中占用存储空间大小的量度,用大O表示,记作S(n)=O(f(n))。常见的空间复杂度按照从低到高的顺序,包括O(1)、O(n)、O(n2)等。其中递归算法的空间复杂度和递归深度成正比。
  • 推导复杂度的原则
    1.与具体的常系数无关,O(n)和O(2n)表示同样的复杂度
    2.复杂度相加的时候,选择最高阶作为结果,也就是说O(n2)和O(n2)+O(n)表示的是同样的复杂度。
    3.O(1)也是表示一个特殊的复杂度,即任务与算例个数n无关。

相关文章

  • 数据结构与算法 理论笔记

    衡量程序运行的效率——复杂度 时间复杂度 定义:定性描述该算法的运行时间主要影响关系:代码结构 常用经验 顺序结构...

  • 01:复杂度:如何衡量程序运行时的效率

    写在前面 在python语言中,并没有直接使用数组这个概念,而是使用列表(list)和元祖(tuple)这两种集合...

  • 简单数据结构

    复杂度 一个算法的复杂度,会极大影响程序运行的效率,复杂度又分为时间复杂度和空间复杂度,时间复杂度取决于程序运行时...

  • 复杂度分析

    什么是复杂度? 算法的复杂度是粗略衡量一个算法执行效率的方法,分为时间复杂度和空间复杂度。 时间复杂度:估算程序指...

  • 究竟什么是时间复杂度,怎么求时间复杂度,看这一篇就够了

    究竟什么是时间复杂度 时间复杂度就是用来方便开发者估算出程序的运行时间 我们该如何估计程序运行时间呢,我们通常会估...

  • o(logn^2)的冒泡、插入、选择排序

    最常见的排序算法时间复杂度的比较: 时间复杂度 如何衡量一个排序算法的指标 1.执行效率: 包括最好、最坏、平均的...

  • 杂项 《重学数据结构与算法》重视方法论

    衡量程序运行的效率 时间复杂度一个顺序结构的代码,时间复杂度是 O(1)二分查找,或者更通用地说是采用分而治之的二...

  • 2021-05-12

    数据复杂度分析 数据结构和算法本身解决的快和省的问题; 如何衡量的代码的执行效率;时间、空间复杂度分析。 1. 测...

  • 1-6算法的时间复杂度

    算法时间复杂度的记法是什么?求程序的时间复杂度? 大O 如何分析一个算法的时间复杂度?1.用常数1取代运行时间中的...

  • 算法1:概述与排序算法

    1.概述 1.1 简介 1.2 算法效率的衡量 1.2.1 时间复杂度 1.2.2 空间复杂度: 1.3 常见...

网友评论

      本文标题:01:复杂度:如何衡量程序运行时的效率

      本文链接:https://www.haomeiwen.com/subject/nltpahtx.html