二叉树的所有路径
给你一个二叉树的根节点 root
,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]
示例 2:
输入:root = [1] 输出:["1"]
【思路】题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。本图涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
递归
1、递归函数参数以及返回值
要传入根节点,记录每一条路径的path,和存放结果集的result,这里递归不需要返回值,代码如下:
void traversal(TreeNode root, List<Integer> path, List<String> result)
2、确定递归终止条件
if (cur == null) { 终止处理逻辑 }
本题只要找到叶子结点,就开始结束的处理逻辑了(把路径放进result里)。
那么什么时候算是找到了叶子结点呢?是当$cur!=null$,其左右孩子都为空的时候,就找到了叶子结点。所以本题的终止条件是:
if (cur.left == null && cur.right == null) { 终止处理逻辑 }
3、确定单层递归逻辑
整体代码如下:(看代码可以大致理解,读流程太繁琐了)
递归+回溯
//递归法 class Solution { public List<String> binsryTreePaths(TreeNode root) { List<String> res = new ArrayList<>();//存最终的结果 if (root == null) { return res; } List<Integer> paths = new ArrayList<>();//作为结果中的路径 traversal(root, paths, res); return res; } private void traversal(TreeNode root, List<Integer> pths, List<String> res) { paths.add(root.val);// 前序遍历,中 //遇到叶子结点 if (root.left == null && root.right == null) { //输出 StringBuilder sb = new StringBuilder();//StringBuilder用来拼接字符串,速度更快 for (int i = 0; i < path.size()-1; i++) { sb.append(paths.get(i)).append("->"); } sb.sppend(paths.get(paths.size() - 1)); //记录最后一个节点 res.add(sb.toString()); //收集一个路径 return; } // 递归和回溯是同时进行,所以要放在同一个花括号里 if (root.left != null) { traversal(root.left, paths, res); paths.remove(paths.size() - 1);//回溯 } if (root.right != null) { //右 traversal(root.right, paths, res); paths.remove(paths.size() - 1);//回溯 } } }
//方法二 class Solution { List<String> result = new ArrayList<>(); public List<String> binaryTreePaths(TreeNode root) { deal(root, ""); return result; } public void deal(TreeNode node, String s) { if (node == null) return; if (node.left == null && node.right == null) { result.add(new StringBuilder(s).append(node.val).toString()); return; } String tmp = new StringBuilder(s).append(node.val).append("->").toString(); deal(node.left, tmp); deal(node.right, tmp); } }