一、前提
写给自己的提醒,工程里讲重设计轻coding,刷题也一样,重思路逻辑轻coding。在纸上把整体思路按逻辑写好coding就简单了,如果上来就直接大脑跟着手敲的代码走就很容易陷进去误区。
二、整体知识结构梳理
1、数据结构
1. 一维结构:
基础结构:数组(List 可变数组由ArrayList和LinkedList实现)、链表、集合(Set)、Map
高级结构:栈(Stack)、队列(Queue由LinkedList等实现)、双端队列(Deque由LinkedList等实现)
2. 二维结构:
基础结构:树、图
高级结构:BST(二叉搜索树)、红黑树等
3. 特殊类:
位运算、布隆过滤器、LRU Cach等
不难看出高级结构通常由基础结构实现多加了些功能而已,例如 大小堆 PriorityQueue 即维护一棵树
2、算法部分
任何题的逻辑结构都是比较小的,一个复杂问题能通过三十行内代码解决一定是不断重复最小逻辑单元,所以困难问题的解决在于找到最小的逻辑结构
1. 基础:
跳转:if-else,switch,goto loop
循环:for,foreach,while,do while
递归(分治、回溯等):recursion
2. 高级算法:
搜索遍历:Dfs,Bfs
二分查找:适用于有序状态
贪心:适用范围小 需要自己判断最后是否最优
数学、几何思路等:自主练习,例如排列组合问题等
注意
Dp:Dp泛化思路首先想到是因为解决最优问题
- 1.找子问题 :等到最终结果需要的最近最优的问题答案是什么
- 2.状态定义 :即dp数组代表的什么(这里很重要)
- 3.dp方程 :当你前两步有思路dp方程就顺理成章了
题需要多练习自己找题感 不然思路啥的都没用
3、时间复杂度
有些时候可以通过想到的解题最优时间复杂度来限定相应算法,帮助自己想到一些思路,需要掌握常见算法思路的时间复杂度
1.O(logn) :二分查找 、欧几里得(最大公约数求法)、幂运算
2.O(n):二叉树的遍历(前中后序)、有序二维矩阵遍历(注意遍历开始位置 剑指offer类似题型)
3.O(nlogn):快排、归并排序、堆排序等
注意:有非常多的衍生题型可以由相应算法的“副产物”解决
例如归并排序的过程可以解决一道跟索引值和数大小的问题,好像叫翻转对,二叉树的前中后续遍历方式可以解决一些验证二叉树的问题,例如二叉树的直径。树的问题通常可以用递归解决,注意眼前一层的逻辑解决好就可以,不要试图大脑递归所有状态
做个记号,具体到各种结构、算法题型相应的思路和通用解题模式慢慢写