leecode255——二叉树的所有路径代码及示例

文章详细阐述了如何使用递归法解决二叉树的路径问题,通过确定终止条件(叶子节点),确定函数参数(根节点,结果集)和单层递归逻辑(根节点->左子树->右子树),实现了前序遍历。在遍历过程中,当遇到叶子节点时,将路径转换为字符串并添加到结果集中。最后通过示例解释了递归和回溯的过程。
摘要由CSDN通过智能技术生成

🔎递归法:

既然是递归法,递归三部曲:

(1)确定终止条件:

对二叉树的路径,遍历到叶子节点结束。本题要找到叶子节点才开始处理后续流程,那什么时候算是找到了叶子节点,即当root不为空,并且root.leftnull&&root.rightnull则算作找到叶子节点。

(2)确定函数参数及返回值

该题要求计算二叉树的路径,函数参数应该为遍历根节点,因此传入根节点,包括一个存放结果集的res,参数无返回值。

(3)确定单层递归逻辑

因为是谦虚遍历,所以就是处理中间节点,中间节点就是我们要处理的路径节点,将其加入到结果集中,
前序遍历的顺序是:根节点、左子树、右子树。
在本题同样也是这个顺序:将根节点加入路径,递归左子树,递归右子树。
对于左子树和右子树来说,也都是同样的操作。
self.getPaths(root.left, path, res)
self.getPaths(root.right, path, res)

对于二叉树的所有路径中的每条路径,当遍历到叶子节点的时候为当前路径的结束。并且将当前路径加入结果集。
如果当前节点是叶子节点,将当前路径加入结果集

if root.left == None and root.right == None:
res.append(path)

🔎代码思路如下:

🌷1.首先定义一个存放结果的列表,因为最后存放结果是一个字符串类型,所以定义的结果类型是字符串类型的结果。
 List<String> res = new ArrayList<>();// 存最终的结果
🌷2.当传入的根节点为空时,则直接返回结果。
if(root==null){
	return res;
}
🌷3.当节点不为空的时候,创建一个存放路径节点的列表path,因为存放的是整数节点,所以定义的是一个整数类型的path列表。
 List<Integer> paths = new ArrayList<>();// 作为结果中的路径
🌷4.创建一个遍历方法,传入节点,路径节点,结果集。
(1)进入该遍方法后,首先将前面不为空的“根节点”加入到路径中。然后判断当前“根节点”的左节点和右节点是否为空,因为我们认为只有到达叶子节点后,才认为当前路径遍历完成。
(2)如果左右节点都为空,则创建一个StringBuilder字符串对象,因为此时需要将path中存放的结果集变为题中要求的形式(例如:1->2->3)。
(3)我们则使用for循环遍历最后一个元素之前的所有元素,并将其加入到StringBuilder对象中,在取出的节点后加上题目要求的“->”符号。
(4)在遍历完成后,还剩下最后一个元素没有读取,则读取最后一个节点加入到StringBuilder对象中,并将其转为字符串加入到结果集。并返回结果。
 		paths.add(root.val);// 前序遍历,中
        // 遇到叶子结点
        if (root.left == null && root.right == null) {
            // 输出
            StringBuilder sb = new StringBuilder();// StringBuilder用来拼接字符串,速度更快
            for (int i = 0; i < paths.size() - 1; i++) {
                sb.append(paths.get(i)).append("->");
            }
            sb.append(paths.get(paths.size() - 1));// 记录最后一个节点
            res.add(sb.toString());// 收集一个路径
            return;
        }
🌷 5.当“根节点”的左右子树不为空时,则分别递归回溯遍历左子树和右子树。
 // 递归和回溯是同时进行,所以要放在同一个花括号里
        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);// 回溯
        }
    }

📚示例:

在这里插入图片描述

🔎流程如下:

🟢(1)首先传入根节点1,不为空,创建路径列表path和结构列表res,
🟢 (2)进入traversal方法,将1加入到路径列表中,此时path=[1,],判断该节点的左右子树是否为空,不为空
🟢(3)则递归处理左子树2,左子树不为空,则进入traversa方法,将2加入到path列表中,此时path=[1,2,];
(4)此时2的左右节点都为空,则认为找到了到叶子结点的路径,则将path=[1,2]处理为1->2存入到结果集res中.
🟢(5)接下来回溯,将2从path中删除,此时path=[1],则继续往下执行,1的右节点3不为空,递归处理右节点,则继续进入traversal方法中,将3加入到path,此时path=[1,3];
🟢(6)3的左右节点不为空,则进行判断3.left是否为空,不为空,进入traversal方法中继续遍历,将4加入到path,此时path=[1,3,4],而4的左右节点都为空,则按代码处理为1->3->4加入到res结果集。
🟢(7)然后将4从path删除,此时path=[1,3],再判断3的右节点,为空,所以执行回溯操作,将 3 从 paths中删除,此时 paths = [1]。递归处理完毕,将 1 从 paths中删除,此时 paths 变为空列表。返回结果列表 res,其中包含两个字符串 “1->2” 和 “1->3->4”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值