时间复杂度和空间复杂度(Python)

时间复杂度:

        时间复杂度通常用Big O notation来表示,常见的时间复杂度有:

  • O ( 1 ) O(1) O(1):常数复杂度
  • O ( l o g n ) O(logn) O(logn):对数复杂度
  • O ( n ) O(n) O(n):线性时间复杂度
  • O ( n 2 ) O(n^2) O(n2):平方
  • O ( n 3 ) O(n^3) O(n3):立方
  • O ( 2 n ) O(2^n) O(2n):指数
  • O ( n ! ) O(n!) O(n!):阶乘

        只看最高复杂度的运算,不考虑系数,比如线性时间复杂度 O ( n ) O(n) O(n),并不意味着,程序执行了 n n n次,也可能是 2 n 2n 2n次,但在描述时间复杂度时,通常忽略系数。
O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 2 l o g n ) < O ( n 3 ) O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^2logn)<O(n^3) O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)
在这里插入图片描述

        以下以Python为例,举出各种程序情况下的时间复杂度:

1. O ( 1 ) O(1) O(1):常数复杂度
'''程序1:'''
a = 500
print("a 的值为:",a)
'''程序2:'''
b = 1000
print(a)
print(b)

        上面的两个程序分别执行了1次和2次,省略常数,他们的时间复杂度都记为 O ( 1 ) O(1) O(1)

2. O ( l o g n ) O(logn) O(logn):对数复杂度
nums = [1,2,3,4]
key = 5
count = 0
l, r = 0, len(nums)-1
while l<r:
    mid = (l+r)//2
    if nums[mid] == key:
        count += 1
        break
    elif nums[mid] >key:
        count += 1
        r = mid-1
    else:
        count += 1
        l = mid +1
print('程序共被执行了:',count,'次')

        对数时间复杂度最经典的例子是折半查找。但这半查找可能不是很直观,下面是一个非常简单的例子:

n = 8
count = 0
while n>1:
    n = n//2
    count += 1
print('程序共被执行了:',count,'次')
程序共被执行了: 3
3. O ( n ) O(n) O(n):线性时间复杂度
n = 5
count= 0
for i in range(n):
	count+=1
print('程序共被执行了:',count,'次')
程序共被执行了: 5

        最经典的时间复杂度为 O ( n ) O(n) O(n)的结构为一层for循环(还有二叉树的遍历前中后层序,图的遍历,BFS,DFS:每个结点访问且仅一次),可以看到,当n为5时,程序执行5次,当n为100时,程序执行100次,时间复杂度随着n的变化作线性变化。

4. O ( n 2 ) O(n^2) O(n2):平方
'''程序1:'''
n = 5
count = 0
for i in range(n):
    for j in range(n):
        count += 1
print('程序共被执行了:',count,'次')
程序共被执行了: 25

        最经典的时间复杂度为 O ( n 2 ) O(n^2) O(n2)的结构为二层for循环

'''程序2:'''
n = 5
count = 0
for i in range(n):
    for j in range(i):
        count += 1
print('程序共被执行了:',count,'次')
程序共被执行了: 10

        上述程序2一共被执行了: ( 1 + n − 1 ) ∗ ( n − 1 ) / 2 = ( n 2 − n ) / 2 (1+n-1)*(n-1)/2=(n^2-n)/2 (1+n1)(n1)/2=(n2n)/2,忽略常数系数以及只看最高复杂度,即为 O ( n 2 ) O(n^2) O(n2)

5. O ( n 3 ) O(n^3) O(n3):立方
n = 5
count = 0
for i in range(n):
    for j in range(n):
        for k in range(n):
            count += 1
print('程序共被执行了:',count,'次')
程序共被执行了: 125

        最经典的时间复杂度为 O ( n 3 ) O(n^3) O(n3)的结构为三层for循环

6. O ( 2 n ) O(2^n) O(2n):指数

求斐波拉契数列的第n项(递归):

n = 6
def fib(n):
    if n<2:return n
    return fib(n-1)+fib(n-2)
print('斐波拉契',n,'为:',fib(n))
斐波拉契 6 为: 8

可以看下该程序的执行树:
在这里插入图片描述

7. O ( n ! ) O(n!) O(n!):阶乘

空间复杂度

  • 如果代码开了数组,则为数组长度
  • 如果有递归,则为递归深度
  • 如果有数组有递归,取最大值
  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔的菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值