算法与数据结构
概述
数据结构与算法的内容分布
算法的复杂度
大O表示法
- 多段代码组合,只看最高复杂度的运算
复杂度的代码示例
O(1)
因为其是常数计算
O(N)
因为,需要循环N次
O(N^2)
因为,内外层均循环N次
O(log(N))
循环次数是x,i*2**x=n,则x=log2(n/i)。
O(K^N)
循环2^N
O(N!)
循环次数为n的阶乘
时间复杂度曲线图
扫描二维码关注公众号,回复:
5561656 查看本文章
- 优化算法复杂度,在大数据、多访问量、高并发时,能大大节省资源。
习题
To calculate: 1+2+3+…+n
O(N)
傻算/硬算
O(1)
递归(recursion)的时间复杂度
Fibonacci array: 1, 1, 2, 3, 5, 8, 13, 21, 34, …
F(n) = F(n-1)+F(n-2)
# 递归
def fib(n):
if n == 0 and n == 1:
return n
return fib(n-1) + fib(n-2)
Fib(6)
其时间复杂度不是O(N),而是类似O(2^N),即指数级时间复杂度。
其是效率较糟糕的算法。
常见算法的时间复杂度
基于 主定理/主定律(Master Theorem)
- 二分查找:O(logN)
- 二叉树遍历:O(N)
- 排序二维矩阵查找(降维)
- 一维:O(logN)
- 二维:O(N)
- 快排、归并排序:O(N * logN)
常见算法的时间复杂度表
通过LeetCode进行练习
- Deliberate Practicing
- 坚持、刻意练习
- 练习缺陷、弱点部分
- 不舒服、不爽、枯燥(完全正常)
算法切题四件套
- Clarification:明确题意
- Possible solutions:(多种解法)
- compare(time/space)
- Optimal(加强)
- Coding(多写)
- Test cases(测试案例)
示例:Two Sum
- 明确题意(难点 和 数据陷阱)
- 多种解法
- 两层循环,暴力枚举
- 改进:枚举x,然后判断9是否在该数组
- 寻求反馈
- leetCode查看solution和discuss
Array
- Access:O(1)
- Insert:O(N)
- Delete:O(N)
数组结构
Linked List
优化Array的插入和删除
- Access:O(N)
- Insert:O(1)
- Delete:O(1)
链表结构
单链表
单指针指向后继
双链表
既有前驱,也有后继