[hello算法] 02复杂度

1.算法效率评估

(1)时间效率:算法运行速度的快慢

(2)空间效率:算法占用内存空间的大小

想平常论文中评定一个方法的优劣时,都会有一种实际测试和另一种理论估算的方法。实际测试多受限于设备条件、时间周期、计算资源等客观条件,难以实现;因此,考虑理论估算方法。

渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析

简而言之,与输入数据的大小相关。即随着输入数据大小的增加,算法执行所需时间和空间的增长趋势。

  • “时间和空间资源”分别对应时间复杂度(time complexity)空间复杂度(space complexity)
  • “随着输入数据大小的增加”意味着复杂度反映了算法运行效率与输入数据体量之间的关系。
  • “时间和空间的增长趋势”表示复杂度分析关注的不是运行时间或占用空间的具体值,而是时间或空间增长的“快慢”。(???趋势?后续需要更多理解

2.迭代

(1)for循环-------适合在预先知道迭代次数时使用

在K聚类工况划分中,使用的就是for循环,对于其迭代次数,是按照一定经验设定。

时间复杂度描述的是“线性关系”

(2)while循环

在 while 循环中,程序每轮都会先检查条件,如果条件为真,则继续执行,否则就结束循环。

在稳态判别中,使用的就是while循环,对于其迭代次数,是根据其(当前序号+窗长)不超过数据的总长为终止条件。--------[滑窗算法]

(3)嵌套循环

在这种情况下,函数的操作数量与 𝑛2 成正比,或者说算法运行时间和输入数据大小 𝑛 成“平方关系”。

我们可以继续添加嵌套循环,每一次嵌套都是一次“升维”,将会使时间复杂度提高至“立方关系”“四次方关系”,以此类推。

3.递归

递归(recursion
程序不断深入地调用自身,通常传入更小或更简化的参数,直到达到“终止条件”。触发“终止条件”后,程序从最深层的递归函数开始逐层返回,汇聚每一层的结果。
"""
求和函数的递归  n=3
(1)3+recur(2)
(2)3+2+recur(1)
(3)3+2+1=6
--------------
存储局部变量n
(1)3
(2)2+recur(1)
 (3) 3+3=6    
"""
def recur(n: int) -> int:
    """递归"""
    # 终止条件
    if n == 1:
        return 1
    # 递:递归调用
    res = recur(n - 1)
    # 归:返回结果
    return n + res
迭代递归
“自下而上”地解决问题。从最基础的步骤开始,然后不断重复或累加这些步骤,直到任务完成。自上而下”地解决问题。将原问题分解为更小的子问题,这些子问题和原问题具有相同的形式。接下来将子问题继续分解为更小的子问题,直到基本情况时停止(基本情况的解是已知的)。
以上述求和函数为例,设问题 𝑓(𝑛)=1+2+⋯+𝑛 。
在循环中模拟求和过程,从 1 遍历到 𝑛 ,每轮执行求和操作,即可求得 𝑓(𝑛) 。将问题分解为子问题 𝑓(𝑛)=𝑛+𝑓(𝑛−1) ,不断(递归地)分解下去,直至基本情况 𝑓(1)=1 时终止。

(1)

递归函数每次调用自身时,系统都会为新开启的函数分配内存,以存储局部变量、调用地址和其他信息等。这将导致两方面的结果。

  • 函数的上下文数据都存储在称为“栈帧空间”的内存区域中,直至函数返回后才会被释放。因此,递归通常比迭代更加耗费内存空间
  • 递归调用函数会产生额外的开销。因此递归通常比循环的时间效率更低

(2)尾递归

如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空间效率上与迭代相当。这种情况被称为尾递归(tail recursion)

普通递归尾递归
当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下文。递归调用是函数返回前的最后一个操作,这意味着函数返回到上一层级后,无须继续执行其他操作,因此系统无须保存上一层函数的上下文
求和操作是在“归”的过程中执行的,每层返回后都要再执行一次求和操作。求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。

4.递归树

给定一个斐波那契数列 0,1,1,2,3,5,8,13,… ,求该数列的第 𝑛 个数字。

草稿:n=1 f(1)=0    n=2  f(2)=1   n=3  f(3)=1

考虑递归的话,遵循一个原则,就是自上而下,即将一个复杂的求解问题(多元问题)逐层拆解为多个简单的一元问题。【分治--分而治之】

对于该题来说,求解第n个数,即f(n)。之后是考虑到如何拆解的问题,这时候就要思考这组数列中所具有的关系式。从上述数列中发现(不能叫发现,叫看网页得到的知识,没有自己推理):每个数字等于前两个数字之后,从第三个数字开始,前两个数字固定不变。

哦!华生发现了盲点:前两个数字固定不变,那就将他们作为终止条件,即所能划分到的最小单元组(固定值)。推导斐波那契数列的公式为f(n)=f(n-1)+f(n-2)

迭代递归
实现方式循环结构函数调用自身
时间效率效率通常较高,无函数调用开销每次函数调用都会产生开销
内存使用通常使用固定大小的内存空间累积函数调用可能使用大量的栈帧空间
适用问题适用于简单循环任务,代码直观、可读性好适用于子问题分解,如树、图、分治、回溯等,代码结构简洁、清晰

  • 55
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值