【LeetCode】最长同值路径 [M](二叉树)

166 篇文章 0 订阅
78 篇文章 37 订阅
给定一个二叉树,找到最长的路径,该路径中的每个节点具有相同值。路径可以经过也可以不经过根节点。文章提供了一个解决方案,通过递归处理每个节点来找出最长的同值路径,并返回最大路径长度。
摘要由CSDN通过智能技术生成

687. 最长同值路径 - 力扣(LeetCode)

一、题目

给定一个二叉树的 root ,返回 最长的路径的长度 ,这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。

两个节点之间的路径长度 由它们之间的边数表示。

示例 1:

输入:root = [5,4,5,1,1,5]
输出:2

示例 2:

输入:root = [1,4,5,4,4,5]
输出:2

提示:

  • 树的节点数的范围是 [0, 104] 
  • -1000 <= Node.val <= 1000
  • 树的深度将不超过 1000 

二、代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 建设以x节点为头的树,返回两个信息
    public class Info {
        // 在一条路径上:要求每个节点通过且只通过一遍
        public int max; // 路径必须从x出发且只能往下走的情况下,路径的最大距离
        public int len; // 路径不要求必须从x出发的情况下,整棵树的合法路径最大距离

        public Info(int max, int len) {
            this.max = max;
            this.len = len;
        }
    }

    public int longestUnivaluePath(TreeNode root) {
        if (root == null) {
            return 0;
        }

        return process(root).max - 1;
    }

    public Info process(TreeNode x) {
        // 如果递归到空姐点,直接返回info(0,0)
        if (x == null) {
            return new Info(0, 0);
        }

        TreeNode left = x.left;
        TreeNode right = x.right;
        // 左树上,不要求从左孩子出发,最大路径
		// 左树上,必须从左孩子出发,往下的最大路径
        Info leftInfo = process(left);
        // 右树上,不要求从右孩子出发,最大路径
		// 右树上,必须从右孩子出发,往下的最大路径
        Info rightInfo = process(right);

        // 1、必须从x出发的情况下,往下的最大路径
        // 初始路径只有x一个节点,len初始化为1
        int len = 1;
        // 先去看x的左子树的根节点,val是不是和x一样,如果一样就可以连成一条路径,更新len
        if (left != null && left.val == x.val) {
            len = leftInfo.len + 1;
        }
        // 再去用相同的标准判断右子树,更新len
        if (right != null && right.val == x.val) {
            len = Math.max(len, rightInfo.len + 1);
        }

        // 2、不要求必须从x出发(路径可以路过x,也可以不路过x),最大路径
        // len:从x出发,只往一侧向下延伸的最大同值路径长度
        // Math.max(leftInfo.max, rightInfo.max):以x为根的树上,不路过x节点的最大同值路径长度
        // 上面两者取最大值
        int max = Math.max(len, Math.max(leftInfo.max, rightInfo.max));
        // 然后再去看是不是可以左右两个子树的路径都可以连接到x,这样整个路径就是从左子树到x再到右子树,计算这种情况的路径长度
        if (left != null && right != null && left.val == x.val && right.val == x.val) {
            // 与max比较,尝试推高max
            max = Math.max(max, leftInfo.len + rightInfo.len + 1);
        }

        // 返回当前以x为根的这棵树的info信息
        return new Info(max, len);
    }
}

三、解题思路

x作为当前的根节点

1、与x无关

①最长同值路径在左子树上

②最长同值路径在右子树上

2、与x有关

路径一定会经过x

③路径只有x自己

④路径从x开始往左延伸

⑤路径从x开始往右延伸

⑥路径从x往左右两边延伸

第⑥种情况时,其实④和⑤情况都是满足的,直接用④和⑤的长度相加就能得到⑥的答案。

info需要返回两个信息:

左树上不要求必须从根结点出发的情况下最大路径(路径可以过根节点,也可以不过根节点)

右树上不要求必须从根结点出发的情况下最大路径

+

左树上必须从根结点出发的最大路径(路径必须过根节点,并且起点是当前的根节点)

右树上必须从根结点出发的最大路径

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值