01 ~ 10篇 | 11 ~ 20篇 |
---|---|
01 数据结构与算法总览 | 11 二分查找 |
02 复杂度分析 | 12 动态规划 |
03 数组、链表、跳表 | 13 字典树和并查集 |
04 栈、队列、优先队列、双端队列 | 14 高级搜索 |
05 哈希表、映射、集合 | 15 红黑树和AVL树 |
06 树、二叉树、二叉搜索树 | 16 位运算 |
07 泛型递归、树的递归 | 17 布隆过滤器和LRU缓存 |
08 分治、回溯 | 18 排序算法 |
09 深度优先搜索和广度优先搜索 | 19 高级动态规划 |
10 贪心算法 | 20 字符串算法 |
- 时间复杂度:评估执行程序所需的时间。可以估算出程序对处理器的使用程度。
- 空间复杂度:评估执行程序所需的存储空间。可以估算出程序对计算机内存的使用程度。
设计算法时,时间复杂度要比空间复杂度更容易出问题,所以一般情况一下我们只对时间复杂度进行研究。一般面试或者工作的时候没有特别说明的话,复杂度就是指时间复杂度。
【1】映射
O 表示它的复杂度是关于n的什么一个函数,可以理解为映射,
类似于函数里的f(x),f表示的是关于x的一种映射关系
【2】时间复杂度不考虑系数k,例:
分析方法:
通过一段代码 根据n的不同情况,会运行多少次,来判断该段代码的时间复杂度
样例分析:
一 、O(1):Constant Complexity 常数复杂度
#不论n=?,只执行一次print
#即print(或者循环体代码)执行次数相对n的映射关系是常数C
#即print(或者循环体代码)执行次数不受n值得影响
def f (n=100):
print("你输入的是:",n)
#print 3次,时间复杂度是O(1)|常熟复杂度,没有 O(3)这种说法
#不论n=?,只执行3次print
def f (n=100):
print("你输入的是:",n)
print("你需要输入的是:",n)
print("你已经完成了:",n)
二、O(n):Linear Complexity 线性时间复杂度
#假设 print执行次数为y
#则执行次数y与输入n满足:y=n的线性关系
#print(或循环体代码)时间复杂度是O(n)
#或称为Linear Complexity 线性时间复杂度
def f (n=10):
for i in range(n):
print("当前是第{}次执行".format(i))
#while写法
def f (n=10,i=1):
while i <=n:
print("当前是第{}次执行".format(i))
i+=1
三、O(n^2):N square Complexity 平方
#嵌套循环
#同理,假设 print执行次数为y
#则执行次数y与输入n满足:y=n^2的线性关系
#print(或循环体代码)时间复杂度是O(n^2)
#或称为N square Complexity 平方时间复杂度
def f(n=5):
for i in range(n):
for j in range(n):
print("当前是第{}组,第{}次".format(i,j))
如果是i,j,k三层嵌套就是O(n^3) 立方的时间复杂度
#拓展———两个并列循环——O(n)线性时间复杂度
#print执行次数为y与输入n满足的是:y=2n的线性关系
#时间复杂度不考虑系数k,所以还是O(n)线性时间复杂度
def f(n=5):
for i in range(n):
print(i)
for j in range(n):
print(j)
四、O(log n):Logarithmic Complexity 对数复杂度
#O(log n)的时间复杂度,
#或者O(log2(n)+1)的时间复杂度,不考虑常数项O(log n)
def f(n=100):
i=1
while i <n:
print(i)
i=i*2
归纳推导:
输入(n) | print次数y |
---|---|
1 | 1 |
2 | 2 |
4 | 3 |
8 | 4 |
16 | 5 |
32 | 6 |
64 | 7 |
… | … |
n | log2(n)+1 |
TIPS:关于python中的log函数
#log在python中的简单计算
#默认log=ln,其他底用logk()表示
import numpy as np
import math
print(math.log(4))
print(math.log10(100),np.log10(100))
print(math.log2(4),np.log2(4))
print(math.log(np.e),np.log(np.e))
五、O(2^n):Exxponential Growth 指数复杂度
#Fibonacci斐波那契数列
#指数复杂度通项O(k^n),Fibonacci是O(2^n)
#详细分析过程见下一段:递归下的时间复杂度分析
def fib(n):
if n<=2:
return n
else:
return fib(n-1)+fib(n-2)
一、画递归树/状态树
求Fibonacci的第n项 :F(n)=F(n-1)+F(n-2)
暴力解法: 直接递归,代码见上段:指数复杂度,时间复杂度 O(2^n)
F(6)的状态树:
优化:
二、主定理(Master theorem)
主定理主要是用来解决所有递归函数时间复杂度计算 任何分治或者递归的函数都可以用主定理计算出时间复杂度
常见的四种场景:
三、常见面试题
1.二叉树的遍历-前序、中序、后序 :时间复杂度是多少? 2.图的遍历,时间复杂度是多少?
搜索算法:DFS(深度优先搜索)、BFS(广度优先搜索),时间复杂度是多少?
二分查找:时间复杂度是多少?
程序员职业素养:
时间复杂度优化的简单样例,体验不同程序达成同一个目标的时间复杂度变化
题目:1+2+3+…+n
#解法一:暴力法累加
#时间复杂度 O(n)
def add_n(n):
result = 0
for i in range(1,n+1):
result+=i
return result
#解法二:求和公式 sum = n(n+1)/2
#时间复杂度 O(1)
#注意此处不是n^2的复杂度
def add_n(n):
return n*(n+1)/2
一个好的时间复杂度程序,可以大大降低工程成本,提升工程效率
下一篇: 03 数组、链表、跳表