1、常见时间复杂度

1.1 五大常见时间复杂度(已按优先级排好)

  • O(1):常数阶;
  • O(logn):对数阶,二分查找算法,log一般以2为底数;
  • O(n):线性阶,线性算法;
  • O(nlogn):线性对数阶;
  • O(n^2):平方阶,排序算法;

1.2 常见时间复杂度优先级曲线

**
timg.jpg

2、时间复杂度举例

2.1 常数阶

  • 执行次数不受数据规模n的影响。例如

    1. n = 100
    2. print('hello')
    3. print('hello')
    4. print('hello')
    5. print('hello')
    6. print('hello')
    7. print('hello')
    8. print('hello')
    9. print('hello')
  • 这里的时间复杂度并不是O(8),而是O(1),因为print的次数并不随着数据规模n的增大而增大

  • 时间复杂度为常数阶O(1)


2.2 对数阶

  1. n = 100
  2. i = 1
  3. while i < n:
  4. i = i * 2
  • 每次循环,i*2,离n更近一步,假设执行x次之后,即有x个2相乘后i大于等于n,就会退出循环
  • 于是由2=n得到x=logn,所以这个程序的时间复杂的为O(logn)

2.3 线性阶

  • 一般含有非嵌套循环,随着n的增大,对应执行次数呈线性增长。例如

    1. n = 100
    2. for i in range(n):
    3. print(i)
  • 时间复杂度为O(n)


2.4 平方阶

  • 嵌套的循环,例如

    1. n = 100
    2. for i in range(n):
    3. for j in range(n):
    4. print(i)
  • 时间复杂度为O(n)


3、时间复杂度大小排序

  • O(1)<O(logn)<O(n)<O(nlogn)<O(n)< O(n)<O(2)<O(n!)<O(n)
  • O(n)开始,这些时间复杂度都随数据规模增大,产生很大的变化,故没必要去讨论他们

4、算法的空间复杂度

  • 首先我们要明白,我们在写代码时,完全可以用空间来换取时间。

  • 举个例子,判断某一年是否为闰年,我们可以实现要给算法,每给一个年份,都会通过算法计算得到是否是闰年的结果。

  • 另一种算法就是,建立一个数组,将所有年份按下标的数字对应,如果是闰年,则此数组元素对应的值为1,否则为0

  • 对比两个算法,第一种算法很明显节约空间,但是每一次查询都需要进行运算,而第二种算法,虽然在内存中存了几千个数组,但是每次查询只需要一次索引即可。

  • 这就是典型的空间换时间。

  • 算法的空间复杂度通过计算算法所需的存储空间实现

  • 算法的空间复杂度的计算公式为:S(n)=O(f(n))
    • 其中,n为问题的规模,f(n)为语句关于n所存储空间的函数。

通常,我们都是用”时间复杂度”来指运行时间的需求,是用”空间复杂的”指空间需求。
当直接要求我们求“复杂度”时,通常是指时间复杂度。
显然,对时间复杂度的追求更属于算法的潮流。

原链接:https://blog.csdn.net/weruse/article/details/104579950