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需要返回两个信息:
左树上不要求必须从根结点出发的情况下最大路径(路径可以过根节点,也可以不过根节点)
右树上不要求必须从根结点出发的情况下最大路径
+
左树上必须从根结点出发的最大路径(路径必须过根节点,并且起点是当前的根节点)
右树上必须从根结点出发的最大路径