数据结构与算法之复杂度

一、算法复杂度

  • 什么是算法复杂度?

    算法复杂度一般分为2个维度:时间复杂度和空间复杂度;针对空间复杂度的问题,现在的我们很少去关心了,因为磁盘内存等变得越来越廉价,我们以后说的复杂度一般只针对 时间复杂度

二、如何计算复杂度

估算如下计算次数

  • 1

    # 只执行了 1 次 , 时间复杂度为 O(1)
    def func():
        a = 1
    
  • 2

    # 执行了 10 次 , 有一层循环,时间复杂度为O(n) 
    def func():
    	for i in range(10):
    		a = 1	
    
  • 3

    # 执行了 10*10 = 100 次 , 有两层循环,时间复杂度为O(n^2)
    def func():
    	for i in range(10):
    		for j in range(10):
    			a = 1
    
  • 4

    # 执行了 10+ 9 + 8 + ... + 1 = 55 次
    def func():
    	for i in range(10):
    		for j in range(i, 10):
    			a = 1
    
  • 5

    '''
    用变量代替执行次数, 执行了 n+ (n-1) + (n-2) + ... + 1 = n * ((n+1) / 2)  次
    化简后后:1/2 * n^2 + 1/2 * n
    时间复杂度为:O(1/2 * n^2 + 1/2 * n)
    由于我们一般只保留最高次的项,并且不保留系数,时间复杂度为:O(n^2)
    '''
    def func():
    	n = 10
    	for i in range(n):
    		for j in range(i, n):
    			a = 1
    
  • 6

    '''
    用变量代替执行次数, 执行了 2*(n+ (n-1) + (n-2) + ... + 1) = n * (n+1) 次
    化简后后:n^2 + n
    时间复杂度为:O(n^2 + n)
    由于我们一般只保留最高次的项,并且不保留系数,时间复杂度为:O(n^2)
    '''
    def func():
    	n = 10
    	for i in range(n):
    		for j in range(i, n):
    			a = 1
    			b = 2
    
  • 7.比较5、6 两者时间复杂度相同,但是两者速度不同,不同之处是系数不同, 在n很大的情况下, 系数和非最高次项都是可以省略的

  • 8.如果程序跑得太慢,有可能是一下两方面的原因:
    ①、时间复杂度过大 ②、常数项过大

算法复杂度常数

  1. 两个算法的时间复杂度均为O(n2),但也要区分跑几个n2, 速度是完全不一样的
  2. 系数和非最高此项均可视为常数
  3. 复杂度与速度没有必然联系,常数项在中间起了很大作用
  4. 如果n值越大,常数项的作用越小, 将n看成非常大,常数项便可以被忽略不计

三、常见的时间复杂度示例

  1. 时间复杂度为: O(1) 也就是常数复杂度

    def func():
    	a = 1
    
  2. 空间复杂度为: O(N) 也就是线性复杂度 (通常特征是一层循环)

    def func():
    	n = 10
    	for i in range(n):
    		a = 1
    
    
  3. 多项式复杂度O(N^2) (通常特征是双层循环)

    def func():
    	n = 10
    	for i in range(n):
    		for j in range(i, n):
    			a = 1
    
  4. 指数复杂度O(2^n)

    def func(n):
    	if n <= 1: return n
    	return func(n-1) + func(n-1)
    
  5. 对数复杂度O(log(N))

    # 此项时间复杂度为以2为底的log(N) 即 log2(N)
    def func(n):
    	if n <= 1: return n
    	return func(n // 2) + 1
    
  6. 渐进复杂度O(N)

    def func(n):
    	if n <= 1: return
    	mid = n // 2
    	for i in range(mid+1, n):
    		a = 1
    	func(mid)
    

    相关数学计算公式如下:
    f(n) = f(n/2) + n/2
    f(n) = f(n/4) + n/4 + n/2
    f(n) = f(n/8) + n/8 + n/4 + n/2

    推导出:
    f(n) = n/2 + n/4 + n/8 + … <= n

发布了370 篇原创文章 · 获赞 169 · 访问量 66万+

猜你喜欢

转载自blog.csdn.net/Tyro_java/article/details/93536806