题目257. 二叉树的所有路径 - 力扣(LeetCode)
回溯法
思路
根据中序遍历的顺序,利用递归法,每次遇到叶节点记录结果
- 记录节点需要在递归终止之前
- 收获结果,在递归终止之时
- 回溯的位置,在处理完整个子树之后。比如,处理2的子树之后,包含1-2的链路都被记录了,此时路径里应该删除2,跳到3
代码
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<Integer> path = new ArrayList<Integer>();
List<String> result = new ArrayList<String>();
treePath(root,path,result);
return result;
}
public void treePath(TreeNode node,List<Integer> path,List<String> result) {
path.add(node.val);
if(node.left == null && node.right == null) {
String p = path.get(0).toString();
for(int i = 1;i<path.size();i++) {
p += "->";
p += path.get(i).toString();
}
result.add(p);
return;
}
if(node.left != null) {
treePath(node.left,path,result);
path.remove(path.size() - 1);
}
if(node.right != null) {
treePath(node.right,path,result);
path.remove(path.size() - 1);
}
}
}
迭代法
思路
用一个栈来保存节点和当前路径;
- 对于弹出的节点,用前序遍历的顺序操作,将其右节点+更新当前节点路径,左节点+更新当前节点路径
- 若栈不为空,重复1
代码
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
Stack<Object> stack = new Stack<>();
List<String> res = new ArrayList<>();
stack.push(root);
stack.push(root.val + "");
while(!stack.isEmpty()) {
String path = (String) stack.pop();
TreeNode node = (TreeNode) stack.pop();
if(node.right == null && node.left == null) {
res.add(path);
continue;
}
if(node.right != null) {
stack.push(node.right);
stack.push(path + "->" + node.right.val);
}
if(node.left != null) {
stack.push(node.left);
stack.push(path + "->" + node.left.val);
}
}
return res;
}
}
总结
递归法中比较难想到的是递归函数的参数,不光有记录结果的result,还要有记录路径的path 另外,递归法中回溯的位置,也需要认真画图理解,回溯删除节点, 一定是在处理完当前节点的所有子树之后
迭代法解答此题更容易理解,思路更加清晰直接,难点是,只用一个栈(Object)来同时存储path和node
学习时长:1h