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

这篇博客介绍了如何在二叉树中找到最长交错路径的问题,分别提供了使用广度优先搜索(BFS)和深度优先搜索(DFS)的算法实现。在BFS方法中,通过维护两个映射`f`和`g`记录以节点为结尾的最长交错路径,并使用队列进行节点的遍历。而在DFS方法中,通过递归地遍历左右子节点,更新最长交错路径的长度。最后,返回所有节点中最大路径长度。示例展示了不同输入下的最长交错路径长度。
摘要由CSDN通过智能技术生成

给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:

选择二叉树中 任意 节点和一个方向(左或者右)。
如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
改变前进方向:左变右或者右变左。
重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。

请你返回给定树中最长 交错路径 的长度。

输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3
解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。

在这里插入图片描述
在这里插入图片描述

输入:root = [1,1,1,null,1,null,null,1,1,null,1]
输出:4
解释:蓝色节点为树中最长交错路径(左 -> 右 -> 左 -> 右)。
示例 3:

输入:root = [1]
输出:0

提示:

每棵树最多有 50000 个节点。
每个节点的值在 [1, 100] 之间。

1.采用bfs 方法:
在这里插入图片描述

class Solution {
    //记 f(u)f(u) 为从根到节点 uu 的路径上以 uu 结尾并且 uu 是它
    // 父亲的左儿子的最长交错路径,g(u)g(u) 为从根到节点 uu 的路径
    // 上以 uu 结尾并且 uu 是它父亲的右儿子的最长交错路径

    Map<TreeNode, Integer> f = new HashMap<>();
    Map<TreeNode, Integer> g = new HashMap<>();
    //作为盛放(节点,结果)的集合,二者可以相互转换
    Queue<TreeNode[]> q = new LinkedList<>();
    //这里用来作为队列,一次性放置两个节点(孩子节点,父节点)
    public int longestZigZag(TreeNode root) {
        bfs(root);
        int max = 0;
        //所有节点的结果都放入f,g中,寻找最大值即可
        for(TreeNode node : f.keySet()){
            max = Math.max(max, Math.max(f.get(node), g.get(node)));
        }
        return max;
    }

    void bfs(TreeNode root){
        f.put(root, 0);
        g.put(root, 0);

        q.add(new TreeNode[]{root, null});//放入根节点

        while(!q.isEmpty()){
            //取出
            TreeNode[] now = q.poll();
            TreeNode child = now[0], parent = now[1];
            f.put(child, 0);//先初始化
            g.put(child, 0);

            if(parent != null){//更新f,g的值
                if(parent.left == child){
                    f.put(child, g.get(parent) + 1);//利用刚才的结果
                }
                if(parent.right == child){
                    g.put(child, f.get(parent) + 1);
                }
            }

            //判断child节点是否有子节点,加入队列
            if(child.left != null){
                q.add(new TreeNode[]{child.left, child});
            }
            if(child.right != null){
                q.add(new TreeNode[]{child.right, child});
            }
        }
    }
}

2.dfs方法
在这里插入图片描述

class Solution {
    int max;
    public int longestZigZag(TreeNode root) {
        if(root ==  null) return 0;
        max = 0;
        dfs(root, false, 0);
        dfs(root, true, 0);
        return max;
    }
    void dfs(TreeNode root, boolean flag, int len){
        //其中flag表示当前点的走向,false向左,true向右
        max = Math.max(max, len);//每次遍历的时候都要比较一下

        if(!flag){
            //当前为左,下次应向右
            if(root.left != null){
                dfs(root.left, true, len + 1);//变为true
            }/*else {
                //若没有左子树,则只能向右,下个节点仍然是向左
                dfs(root.right, false, 1);
            }*/
            //并不是一个二选一的过程,都是有可能存在的情况的
            if(root.right != null){
                dfs(root.right, false, 1);//设定root.right仍是向左,
                //因为已经向左走了一段,此时长度为1;
            }
        }else {
            //当前走向向右
            if(root.right != null){
                dfs(root.right, false, len + 1);
            }
            if(root.left != null){
                dfs(root.left, true, 1);
                //重置,root.left应向右
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值