目录
- 基本概念
- 通用模板
- 例子
-
- Leetcode 257. Binary Tree Paths(easy)
- Leetcode 107. Binary Tree Level Order Traversal II(easy)
- Leetcode 40. Combination Sum II(medium)
- Leetcode 199. Binary Tree Right Side View(medium)
- Leetcode 133. Clone Graph(medium)
- Leetcode 207. Course Schedule(medium)
- Leetcode 99. Recover Binary Search Tree(hard)
基本概念
深度优先搜索,一种用于遍历或搜索树或图(树是特殊的图)的算法。 优先沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
广度优先搜索,优先遍历当前节点的所有子节点,再逐层向下遍历。通常需要使用队列进行辅助。
回溯法,本质上就是dfs的思想,可以说是dfs的一种应用,主要的区别在于回溯法需要显式地删除当前步骤的结果,回退至上一步。
通用模板
void dfs(Node node){
if(满足节点条件)
return;
// 对该节点进行操作
doSomething();
// 遍历下一个节点
dfs(node.next);
}
void bfs(Node node){
Queue<Node> q = new LinkedList<>();
q.offer(node);
while(!q.isEmpty()){
Node n = q.poll();
// 对当前节点进行操作
doSomething();
// 将当前节点的子节点加入队列中
q.offer(n.子节点);
}
}
void backtracking(Node node){
if(满足节点条件)
return;
// 对该节点进行操作
doSomething();
// 遍历下一个节点
backtracking(node.next);
// 删除当前结果
deleteNow();
}
例子
Leetcode 257. Binary Tree Paths(easy)
题目描述
分析:因为要输出所有的路径,因此适合采用dfs,每次遍历一条路径,在遍历过程中,需要记录下每一个节点,当遍历到叶节点时存入到结果链表中即可。
class Solution {
// 用于保存结果
private List<String> list = new ArrayList<>();
public List<String> binaryTreePaths(TreeNode root) {
dfs(root, "");
return list;
}
private void dfs(TreeNode root, String s){
// 边界条件
if(root == null)
return;
// doSomething()
// 保存下每个节点
StringBuffer sb = new StringBuffer(s);
if(sb.length() == 0)
sb.append(root.val);
else
sb.append("->").append(root.val);
// 到达叶结点时
if(root.left == null && root.right == null){
list.add(sb.toString());
return;
}
// 遍历下一个节点
if(root.left != null)
dfs(root.left, sb.toString());
if(root.right != null)
dfs(root.right, sb.toString());
}
}
Leetcode 107. Binary Tree Level Order Traversal II(easy)
题目描述
分析:因为题目要求按层输出结果,所以优先想到使用bfs进行搜索。题目要求最后结果需从下向上,则在输出链表中将答案插在链表头部即可。
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
if(root == null)
return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()