【简单算法】什么是复杂度?

简介: 【简单算法】什么是复杂度?

在上一篇文章里,有看到一个简单算法题的2个解法,我们运用了复杂度分析来判断哪个解法更合适。


这里的复杂度,就是用于衡量程序的运行效率的重要度量因素。


虽然有句俗话“不管是白猫还是黑猫,抓到老鼠就是好猫”,这句话是站在结果导向的,没错。但是如果

有个程序要去处理海量数据,一个程序员写的要执行2天,而另一个程序员只要半小时,那么第二种显然更适合

我们的实际需求。


一、什么是复杂度


复杂度是一个关于输入数据量n的函数。


要表示复杂度很简单,用大写O加上括号O()将复杂度包起来就好了。比如这个代码的复杂度是f(n),那就可以写成

O(f(n))


在计算复杂度的时候,有三点需要我们记住:


  • 复杂度与具体常系数无关
  • 多项式级复杂度相加,选择高者为结果
  • O(1)表示特殊复杂度


1、复杂度与具体常系数无关


举个例子,将一个列表反转,不用reverse()。


def demo_1():
    a = [1, 2, 3, 4, 5]
    b = [0 for x in range(0,5)]  #第一个for循环
    n = len(a)
    for i in range(n):   # 第二个for循环
        b[n - i - 1] = a[i]
    print(b)
if __name__ == "__main__":
    demo_1()
===============运行结果==================
D:\Programs\Python\Python36\python.exe D:/练习/leecode/fuzadu.py
[5, 4, 3, 2, 1]
Process finished with exit code 0


可以看到我先用了一个for循环创建了一个跟a列表等长度,元素全是0的列表。


然后再用一个for循环将a里的元素倒序放入b,最终得到一个跟a反序的列表。


其中,每一个for循环的时间复杂度都是O(n),2个加起来就是O(n)+O(n),也等于O(n+n),也等于O(2n)


也就是相当于 一段 O(n)复杂度的代码先后执行两遍,它们的复杂度是一致的。


2、多项式级复杂度相加,选择高者为结果


有了上面的例子,这个也就好理解了。


假设,一个算法的复杂度是O(n²)+O(n),那么可以知道,当n越来越大,也就是输入的数据量越来越大时,n^2的变化率要比n大的多,

所以,这时候我们只取变化率更大的n^2来表示复杂度即可,也就是O(n²)+O(n)等同于O(n²)


3、O(1)表示特殊复杂度


还是借助上面的反转问题,这里再使用第二种解法。


def demo_2():
    a = [1, 2, 3, 4, 5]
    tmp = 0
    n= len(a)
    for i in range(n//2):    #  // 表示整数除法,返回不大于结果的一个最大整数
        tmp = a[i]
        a[i] = a[n -i -1]
        a[n -i -1] = tmp
    print(a)
if __name__ == "__main__":
    demo_2()
==============运行结果==============
D:\Programs\Python\Python36\python.exe D:/练习/leecode/fuzadu.py
[5, 4, 3, 2, 1]
Process finished with exit code 0


跟第一个解法相比,第二个解法少了一个for循环,而且循环次数只是到了列表的一半,那么时间复杂度就是O(n/2)

由于复杂度与具体的常系数无关的性质,这段代码的时间复杂度还是 O(n)


但是在空间复杂度上,第二个解法开辟了一个新的变量tmp,它与数组长度无关。


输入是 5 个元素的数组,需要一个tmp变量输入是 50 个元素的数组,同样只需要一个tmp变量。


因此,空间复杂度与输入数组长度无关,这就是 O(1)


二、分析复杂度


这里就直接上一些经验性的结论,可以直接拿过来用的:


  • 一个顺序结构的代码,时间复杂度是 O(1)
  • 一个简单的 for 循环,时间复杂度是 O(n)
  • 两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),其实也是 O(n)
  • 两个嵌套的 for 循环,时间复杂度是 O(n²)
  • 二分查找,时间复杂度都是 O(logn)


趁热打铁,分析一下下面代码的复杂度:


for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        for (k = 0; k < n; k++) {
        }
        for (m = 0; m < n; m++) {
        }
    }
}


可以先从最里面看,最内层是2个顺序结构的for循环,复杂度是O(n)


中间这层的又嵌套了一个for循环,所以这时候复杂度就变成了O(n^2)


最后,最外层又嵌套了一个for循环,所以最终的复杂度就是O(n^3)


虽然测试工程师的代码对于复杂度要求不高甚至说非常低,但是我觉得理解复杂度,并且会做一些简单的分析

还是很有必要的。

相关文章
|
6月前
|
机器学习/深度学习 存储 算法
【算法与数据结构】复杂度深度解析(超详解)
【算法与数据结构】复杂度深度解析(超详解)
【算法与数据结构】复杂度深度解析(超详解)
|
6月前
|
存储 算法
数据结构与算法:复杂度
数据结构: 数据结构是用于存储和组织数据的方式,以便可以有效地访问和修改数据。不同的数据结构适用于不同类型的应用,并且具体的数据结构可以大幅影响程序的性能。数据结构分为两大类:线性数据结构和非线性数据结构。 算法: 算法是完成特定任务的一系列操作步骤,是解决问题的明确规范。算法的效率通常通过时间复杂度和空间复杂度来评估,即算法执行所需的时间和空间资源。
|
6月前
|
机器学习/深度学习 存储 算法
如何评判算法好坏?复杂度深度解析
如何评判算法好坏?复杂度深度解析
111 0
|
5月前
|
机器学习/深度学习 存储 算法
1 .算法的复杂度(超全)
1 .算法的复杂度(超全)
|
1月前
|
移动开发 算法 前端开发
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
21 0
|
2月前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
57 4
|
2月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
41 1
|
3月前
|
算法
【初阶数据结构】复杂度算法题篇
该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 kmodn 个元素会移动至数组头部,其余元素向后移动 kmodn 个位置。
26 1
|
4月前
|
机器学习/深度学习 存储 算法
【数据结构】算法的复杂度
算法的时间复杂度和空间复杂度
72 1
【数据结构】算法的复杂度