时间复杂度

时间复杂度指输入数据大小为 N 时,算法运行所需花费的时间。统计的是算法的「计算操作数量」,而不是「运行的绝对时间」。因为算法运行时间受到「编程语言 、计算机处理器速度、运行环境」等多种因素影响。

例如,同样的算法使用 Python 或 C++ 实现、使用 CPU 或 GPU 、使用本地 IDE 或力扣平台提交,运行时间都不同。

根据输入数据的特点,时间复杂度具有「最差」、「平均」、「最佳」三种情况,分别使用O,Θ,Ω 这三种符号表示。

根据从小到大排列,常见的算法时间复杂度主要有:

O(1) < O(log N) < O(N) < O(N log N) < O(N2) < O(2N) < O(N!)

 

1、常数 O(1) :

运行次数与 N 大小呈常数关系,即不随输入数据大小 N 的变化而变化。

2、线性 O(N) :

循环运行次数与 N 大小呈线性关系,时间复杂度为 O(N) 。

1 def algorithm(N):
2     count = 0
3     for i in range(N):
4         count += 1
5     return count

3、平方 O(N2):

两层循环相互独立,都与 N 呈线性关系,因此总体与 N 呈平方关系,时间复杂度为 O(N2)。 

1 def algorithm(N):
2     count = 0
3     for i in range(N):
4         for j in range(N):
5             count += 1
6     return count

4、指数 O(2N):

生物学科中的 “细胞分裂” 即是指数级增长。初始状态为 1 个细胞,分裂一轮后为 2 个,分裂两轮后为 4 个,……,分裂 N 轮后有 2N个细胞。指数阶常出现于递归。 

1 def algorithm(N):
2     if N <= 0: return 1
3     count_1 = algorithm(N - 1)
4     count_2 = algorithm(N - 1)
5     return count_1 + count_2

 5、阶乘 O(N!):

阶乘阶对应数学上常见的 “全排列” 。即给定 N 个互不重复的元素,求其所有可能的排列方案,则方案数量为:N×(N−1)×(N−2)×⋯×2×1=N! 

1 def algorithm(N):
2     if N <= 0: return 1
3     count = 0
4     for _ in range(N):
5         count += algorithm(N - 1)
6     return count

 6、对数 O(logN) :

对数阶与指数阶相反,指数阶为 “每轮分裂出两倍的情况” ,而对数阶是 “每轮排除一半的情况” 。对数阶常出现于「二分法」、「分治」等算法中,体现着 “一分为二” 或 “一分为多” 的算法思想。 

1 def algorithm(N):
2     count = 0
3     i = N
4     while i > 1:
5         i = i / 2  # >=2
6         count += 1
7     return count

7、线性对数 O(NlogN) :

两层循环相互独立,第一层和第二层时间复杂度分别为O(logN) 和 O(N) ,则总体时间复杂度为 O(NlogN)。 线性对数阶常出现于排序算法,例如「快速排序」、「归并排序」、「堆排序」等

1 def algorithm(N):
2     count = 0
3     i = N
4     while i > 1:
5         i = i / 2
6         for j in range(N):
7             count += 1

说明:此图为每个节点执行N次,然后外部执行logN次(因为一分为二)。

 

posted @ 2021-07-02 10:08  yingfengwu  阅读(678)  评论(0)    收藏  举报