Leetcode二叉树中的最长交错路径

题目描述:

解法:深度优先遍历

思路:

采用深度优先遍历的方式,我们可以从顶向下访问到所有节点。并且遍历下一个子节点时,我们也能够知道子节点是属于父节点的左子树,还是右子树。

所以我们可以为每个节点缓存两个值,一个l表示到达当前节点时,该节点为左子树时的路径数,一个r表示该节点为右子树时的到达路径。 当然,一个节点要么是左子树,要么是右子树,所以l和r其中只有一个有值。

那么在遍历该节点的子节点时,如果子节点是左子树,那么它的l值就是父节点的r值加1. 如果是右子树,就是父节点的l值加1.

参考来源:

作者:林晓东
链接:https://leetcode.cn/problems/longest-zigzag-path-in-a-binary-tree/solutions/913653/dfsduan-duan-ba-xing-dai-ma-you-ya-jie-j-kfyz/

代码解析:

函数longestZigZag是入口函数,通过调用visit函数从根节点开始访问,并将初始的左子树最大长度和右子树最大长度都设为0。最后返回最长的zigzag路径长度。

visit函数中,首先更新最大长度max,取左子树最大长度leftMax和右子树最大长度rightMax的较大值。然后判断当前节点是否为空,如果为空,则结束访问。接着访问左子树,如果左子树存在,以当前节点作为右拐点,继续向右子树方向访问,即visit(root.left, rightMax + 1, 0),左子树最大长度加1,右子树最大长度重置为0。然后访问右子树,如果右子树存在,以当前节点作为左拐点,继续向左子树方向访问,即visit(root.right, 0, leftMax + 1),右子树最大长度加1,左子树最大长度重置为0。

private int max = 0;

    public int longestZigZag(TreeNode root) {
        // 从根节点开始访问,初始的左右子树最大长度都为0
        visit(root, 0, 0);
        // 返回最长的zigzag路径长度
        return max;
    }

    private void visit(TreeNode root, int leftMax, int rightMax) {
        // 更新最大长度,取左右子树最大长度的较大值
        max = Math.max(max, Math.max(leftMax, rightMax));

        // 如果当前节点为空,结束访问
        if (root == null) {
            return;
        }

        // 访问左子树
        if (root.left != null) {
            // 在左子树中,以当前节点作为右拐点,继续向右子树方向访问,左子树最大长度加1,右子树最大长度重置为0
            visit(root.left, rightMax + 1, 0);
        }

        // 访问右子树
        if (root.right != null) {
            // 在右子树中,以当前节点作为左拐点,继续向左子树方向访问,右子树最大长度加1,左子树最大长度重置为0
            visit(root.right, 0, leftMax + 1);
        }
        /*
        * 上面为什么往左拐是rightMax + 1,右拐leftMax + 1?
        * 首先,往那边拐,对应的函数参数位置+1这个好理解
        * 现在讲解左拐是rightMax + 1,因为你现在是左拐了对吧
        * 然后题目是交叉长度,所以你左拐的长度就得是上一个的右拐的长度,
        * 也就是等同于当前rightMax ,再去+ 1
        * 右拐也同理
        * 每拐一次,也就是每执行一次visit函数,max赋值左大和右大之间的最大值
        * */
    }

 难点:

* 上面为什么往左拐是rightMax + 1,右拐leftMax + 1?
* 首先,往那边拐,对应的函数参数位置+1这个好理解
* 现在讲解左拐是rightMax + 1,因为你现在是左拐了对吧
* 然后题目是交叉长度,所以你左拐的长度就得是上一个的右拐的长度,
* 也就是等同于当前rightMax ,再去+ 1
* 右拐也同理
* 每拐一次,也就是每执行一次visit函数,max赋值左大和右大之间的最大值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值