算法复杂度
1.for循环
1.1遍历整个列表
1 magicians = ['alice', 'david', 'carolina']
2 for magician in magicians:#从列表中取出一个名字,并将其存储在变量magician中。对于列表中的每个名字,Python都将重复执行2处和3处的代码行。
3 print(magician)
对列表中的每个元素,都将执行循环指定的步骤
2.递归,全排列
全排列
全排列算法-递归&字典序实现https://blog.csdn.net/u013309870/article/details/68941284
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。 例如:
1,2,3三个元素的全排列为:
递归:指的是一种通过重复将原问题分解为同类的子问题而解决的方法。在绝大数编程语言中,可以通过在函数中再次调用函数自身的方式来实现递归。
举个例子来说明一下递归算法。比如阶乘的计算方法在数学上的定义为:
根据阶乘计算方法的数学定义,我们可以使用调用函数自身的方式来实现阶乘函数 fact(n)
,其实现代码可以写作:
def fact(n):
if n == 0:
return 1
return n * fact(n - 1)
现在通过实例来说明如何计算时间复杂度
一、时间复杂度
1.阶乘O(n!)
参考资料:
递归全排列 python实现https://blog.csdn.net/qq_42015869/article/details/79996227
Python打印全排列数组https://blog.csdn.net/qq_44193350/article/details/124003759全排列递归与非递归python实现
阶乘时间复杂度一般出现在与「全排列」、「旅行商问题暴力解法」相关的算法中。这类算法随着问题规模 n 的增大,对应计算次数呈阶乘关系增长。
def permutations(arr, start, end):
if start == end:#递归出口
print(arr)
return
for i in range(start, end):#递归体
arr[i], arr[start] = arr[start], arr[i]
permutations(arr, start + 1, end)#调用递归函数
arr[i], arr[start] = arr[start], arr[i]#保持数组值不变,继续下次循环
arr=[1,2,3……n-1,n]
permutations(arr,0,len(arr))
上述代码中实现「全排列」使用了递归的方法。假设数组 arr
长度为 n
,第一层 for
循环执行了 n
次,第二层 for
循环执行了 n - 1
次。以此类推,最后一层 for
循环执行了 1
次,将所有层 for
循环的执行次数累乘起来为 n∗(n−1)∗(n−2)∗…∗2∗1=n! 次。则整个算法的 for
循环中基本语句的执行次数为 n! 次,所以对应时间复杂度为 O(n!)。
注解:
1.递归还需要传递位置参数start+1,表示每次递归待交换元素的位置。
2.但是光这些还不够,回到之前说的循环,交换元素后进行递归,得到的是交换后的排列,那交换前的呢?
3.再将元素交换回原位置即可。因此在交换元素位置后,首先调用递归函数对后续位置进行全排列,再在当前循环内将元素交换回原位置,使得之后的循环能继续交换后续元素,继续递归后续元素。
4.所有递归函数是从递归出口开始返回的,所以每个递归出口都对应一个全排列结果,因此可以在递归出口使用数组添加结果。
二、空间复杂度
相比于算法的时间复杂度计算来说,算法的空间复杂度更容易计算,主要包括「局部变量(算法范围内定义的变量)所占用的存储空间」和「系统为实现递归(如果算法是递归的话)所使用的堆栈空间」两个部分。