数据结构和算法-02.时间复杂度

# CY3761 | 2021-11-29 14:50

# 时间复杂度
# 优化上一课的算法

# 代码执行多久
import time
import types


def handler(algo):
    print('-' * 80)
    stime = time.time()
    
    if isinstance(algo, types.FunctionType):
        c = algo()
    
    etime = time.time()
    
    print('执行时间', (etime - stime), '循环次数', c)


# 这个更优
def algo_02():
    s1 = 0
    s2 = 1000 + 1
    co = 0
    
    for a in range(s1, s2):
        for b in range(s1, s2):
            co += 1
            c = 1000 - a - b  # 基本步骤 计算、赋值 2步骤
            
            if a ** 2 + b ** 2 == c ** 2:
                print(f'a = {a}, b = {b} c = {c}')
    
    return co


handler(algo_02)  # 比上面的更快

# 同一个程序, 其运行的时间都不一定一样
# 但步骤代码都一样
# 用执行的步骤次数描述算法 | 时间频度 T
# 计算这个T
# 赋值 s1 = 0 | 计算赋值 s2 = 1000 + 1 | 赋值 co = 0 | 3 | T = 3
# for a in range(s1, s2): 循环 0~1000 | 1001 | T = 3 + 1001
# for b in range(s1, s2): 循环 0~1000 | 1001 | T = 3 + 1001 * 1001
# 计算 a ** 2 + b ** 2 | 计算  c ** 2 | 判断 a ** 2 + b ** 2 == c ** 2 | 3 | T = 3 + 1001 * 1001 * 3
# 打印 print(f'a = {a}, b = {b} c = {c}') | 1 | T = 3 + 1001 * 1001 * 4
# 返回 return co | 1 | T = 3 + 1001 * 1001 * 4 + 1
print(3 + 1001 * 1001 * 4 + 1)  # 4008008
# 数据规模 n
# T = 3 + n ** 2 * 4 + 1
# 当 n为无穷大时, 时间额度式子中,谁的值最大, 那么时间复杂度就是谁 (两个数计算, 谁更大)
# 3 | 4n | 2 ** n | 1 谁最大 一般是次方数大于积数
# 时间复杂度 O(n**2) | 有点抽象

# 如 T = 3 * n ** 3 + 2 * n ** 2 + 10000
# 忽略 常数项(具体数字进行加或乘) 3* 忽略 2* 忽略 +10000 忽略
# 留下 代数 n的计算 | n**3 n**2 很明显就 n**3胜出
# 时间复杂度 O(n**3)

# 让用户输入两个列表
# 一个列表长度是m
# 另个一个是n
# 对列表就行求和
# 然后比较其大小

# 循环变量 分别求和 再比较大小
# m步 n步 O(m+n)

# 总结
# 计算时,往往只关注时间频度中的最高次项,其他次要项和常数项忽略
# 顺序结构,时间复杂度按加法来计算
# 循环结构,时间复杂度按乘法来计算
# 分支结构,时间复杂度取最大值
# 没有特殊说明时,算法的时间复杂度都是指最坏的时间复杂度

# 时间复杂度
# 最优时间复杂度 – 算法完成工作最少需要多久 | 最优 最少
# 最坏时间复杂度 – 算法完成工作最多需要多久 | 最坏 最多
# 平均时间复杂度 – 算法完成工作平均需要多久 | 平均
# 均摊时间复杂度 – 平均时间复杂度的补充,应用场景极少 | 均摊


在这里插入图片描述

# CY3761 | 2021-11-29 15:44

# 用户输入长度为6的数组,数组由1-6六个数字组成,顺序随机
# 请返回数字6出现的位置

# 给定列表
# 进行遍历
# 判断其值是否等于6
# 如果登录6则返回其索引

import random

a = range(1, 6 + 1)
a = list(a)
random.shuffle(a)  # 列表随机打乱 必须传入列表 改变源列表本身

print(a)

print('-' * 80)
for k, _ in enumerate(a):
    if _ == 6:
        print(k)
        break

print('-' * 80)
for k in range(len(a)):  # 循环 a的长度次数
    if a[k] == 6:
        print(k)
        break

# 如果 6在第一位 那么就属于最优时间复杂度 O(1)
# 如果 6在最后一位 那么就属于最坏时间复杂度 O(n)
# 平均复杂度 (1+2+3+4+5+6)/6 = 21/6 = 7/2 (同时两边除以3) O(n)
# 零和欧太相似了

# 常见的时间复杂度
# 12 | O(1) | 常数阶
# 2n+3 | O(n) | 线性阶
# 3n**2 + 2n + 1 | O(n**2) | 平方阶
# 5log//2n+20 | O(logn) | 对数阶
# 2n+3nlog//2n+19 | O(nlogn) | nlogn阶
# 6n**3+2n**2+3n+4 | O(n3) | 立方阶
# 2**n | O(2**n) | 指数阶

# 注意,经常将log2n(以2为底的对数)简写成logn
# O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

在这里插入图片描述
其实我也不太懂这玩意是啥

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CY3761

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

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

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

打赏作者

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

抵扣说明:

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

余额充值