LeetCode总结(二)BFS/DFS
BFS广度优先遍历
模式比较固定,使用一个队列。
二叉树的层序遍历
无权图最短路径问题
需要处理两个问题:
1. 如何遍历当前cur点的所有邻接点?需要同时考虑边界、这个点的是否为1和是否已经访问过(visited);
答:可以用两个int []数组dx与dy表示所有可能的邻接点(4邻域则长度为4,8邻域则长度为8),然后要遍历某个点的邻接点时,使用一个for循环在当前点上加增量即可:x = cur.x + dx[i], y = cur.y + dy[i]
2. 如何记录当前出列点cur与原点的距离?每个点都存放dist显然太占空间。
答:记录队列的长度cnt,接下来就以这cnt个元素为一组,在这一组检查完之后更新cnt
这道题的变种:
- 不是从左上角到右下角,而是从(x1, y1)到(x2, y2)
- 邻接点为4邻域与8邻域
- 有k次机会可以消去障碍物,LC1293
912 克隆图
130 被围绕的区域
DFS深度优先遍历
对二叉树进行深度优先遍历,分为前序/中序/后序遍历;递归的实现比较简单,也可以用堆栈迭代实现:
- 二叉树的中序遍历:左树->根节点->右树
- 入栈:首先将根节点放入栈,然后一直往左,将左节点放入栈中,直到当前结点为null
- 出栈:然后开始出栈,先把指挥权移交给栈顶,然后出栈一个结点放入结果,回到入栈环节
- 二叉树的前序遍历:
- 基本与中序遍历相同;不同的是输出结点是在入栈时同时输入
- 二叉树的后序遍历
- 用栈实现需要一定的技巧!仍然是入栈和出栈两个阶段不断循环
- LeetCode 98 验证二叉搜索树(左树的所有结点比根节点小,右树所有结点比根节点大,BST总是要用中序遍历解决!)
一个重要结论:一个二叉树是二叉搜索树的充分必要条件是,对该二叉树进行中序遍历得到一个严格递增序列。
迭代中序遍历:注意如何记录上一个值,与当前值进行比较;如果不符合严格增则return false;
递归中序遍历:直接递归地判断当前左子树是否为BST,然后让当前结点与前一个结点比较是否严格升序,在判断当前右子树是否为BST;注意在递归中序遍历下如何记录上一个结点!(利用一个INT_MIN作为pre_val的初始化值)
- LeetCode 99 恢复二叉搜索树
同98,要找到至多两个不符合严格增的相邻点。在递归中序遍历下如何记录上一个结点!(也可以利用一个结点记录上一个结点,这里有一点坑!)
- LeetCode 96 可能的二叉搜索树有多少种?
动态规划容易解决。
- LeetCode 95 生成所有可能的二叉搜索树
- LeetCode 104 二叉树的最大深度(变型:输入二叉树的所有叶子结点)
直接用递归的方法,当前最大深度等于max(left.height, right.heght)+1;时间复杂度O(N),空间复杂度O(height)递归栈
用bfs迭代遍历整个二叉树(使用队列),记录深度;时间复杂度O(N),空间复杂度最高可能O(N)